From 09dac0d30a45181d1617941209fe4a104cbe3ceb Mon Sep 17 00:00:00 2001 From: wsdjeg Date: Sat, 28 May 2022 15:29:51 +0800 Subject: [PATCH] chore(calendar): use bundle calendar.vim --- autoload/SpaceVim/layers/tools.vim | 2 +- bundle/README.md | 1 + bundle/calendar.vim/.github/workflows/ci.yaml | 36 + bundle/calendar.vim/.gitignore | 1 + bundle/calendar.vim/LICENSE | 21 + bundle/calendar.vim/README.md | 129 ++ bundle/calendar.vim/autoload/calendar.vim | 64 + .../autoload/calendar/argument.vim | 320 +++++ .../calendar.vim/autoload/calendar/async.vim | 122 ++ .../autoload/calendar/autocmd.vim | 98 ++ .../calendar.vim/autoload/calendar/cache.vim | 236 ++++ .../calendar.vim/autoload/calendar/cipher.vim | 58 + .../calendar.vim/autoload/calendar/color.vim | 490 ++++++++ .../autoload/calendar/constructor/day.vim | 155 +++ .../calendar/constructor/day_hybrid.vim | 73 ++ .../autoload/calendar/constructor/month.vim | 155 +++ .../autoload/calendar/constructor/view.vim | 172 +++ .../calendar/constructor/view_clock.vim | 221 ++++ .../calendar/constructor/view_days.vim | 778 ++++++++++++ .../calendar/constructor/view_months.vim | 348 ++++++ .../calendar/constructor/view_textbox.vim | 362 ++++++ .../calendar/constructor/view_ymd.vim | 127 ++ .../autoload/calendar/constructor/year.vim | 117 ++ .../autoload/calendar/controller.vim | 280 +++++ .../autoload/calendar/countcache.vim | 88 ++ bundle/calendar.vim/autoload/calendar/day.vim | 78 ++ .../autoload/calendar/day/austria.vim | 27 + .../autoload/calendar/day/austriastyria.vim | 27 + .../autoload/calendar/day/british.vim | 26 + .../autoload/calendar/day/bulgaria.vim | 26 + .../autoload/calendar/day/canada.vim | 26 + .../autoload/calendar/day/default.vim | 26 + .../autoload/calendar/day/estonia.vim | 26 + .../autoload/calendar/day/france.vim | 26 + .../autoload/calendar/day/germany.vim | 26 + .../autoload/calendar/day/germanyprussia.vim | 26 + .../autoload/calendar/day/greece.vim | 26 + .../autoload/calendar/day/gregorian.vim | 75 ++ .../autoload/calendar/day/holland.vim | 26 + .../autoload/calendar/day/hungary.vim | 26 + .../autoload/calendar/day/italy.vim | 26 + .../autoload/calendar/day/japan.vim | 30 + .../autoload/calendar/day/julian.vim | 66 + .../autoload/calendar/day/poland.vim | 26 + .../autoload/calendar/day/portugal.vim | 26 + .../autoload/calendar/day/russia.vim | 26 + .../autoload/calendar/day/spain.vim | 26 + .../autoload/calendar/day/turkey.vim | 26 + .../calendar.vim/autoload/calendar/day/us.vim | 26 + .../calendar.vim/autoload/calendar/echo.vim | 52 + .../calendar.vim/autoload/calendar/event.vim | 136 ++ .../autoload/calendar/event/google.vim | 68 + .../autoload/calendar/event/local.vim | 250 ++++ .../autoload/calendar/google/calendar.vim | 618 ++++++++++ .../autoload/calendar/google/client.vim | 196 +++ .../autoload/calendar/google/task.vim | 440 +++++++ .../autoload/calendar/mapping.vim | 243 ++++ .../calendar.vim/autoload/calendar/mark.vim | 56 + .../autoload/calendar/message.vim | 43 + .../autoload/calendar/message/default.vim | 35 + .../autoload/calendar/message/en.vim | 107 ++ .../autoload/calendar/message/ja.vim | 113 ++ .../calendar.vim/autoload/calendar/model.vim | 156 +++ .../calendar.vim/autoload/calendar/pixel.vim | 64 + .../calendar.vim/autoload/calendar/pixel/100 | 5 + .../calendar.vim/autoload/calendar/pixel/101 | 5 + .../calendar.vim/autoload/calendar/pixel/102 | 5 + .../calendar.vim/autoload/calendar/pixel/103 | 5 + .../calendar.vim/autoload/calendar/pixel/104 | 5 + .../calendar.vim/autoload/calendar/pixel/105 | 5 + .../calendar.vim/autoload/calendar/pixel/106 | 5 + .../calendar.vim/autoload/calendar/pixel/107 | 5 + .../calendar.vim/autoload/calendar/pixel/108 | 5 + .../calendar.vim/autoload/calendar/pixel/109 | 5 + .../calendar.vim/autoload/calendar/pixel/110 | 5 + .../calendar.vim/autoload/calendar/pixel/111 | 5 + .../calendar.vim/autoload/calendar/pixel/112 | 5 + .../calendar.vim/autoload/calendar/pixel/113 | 5 + .../calendar.vim/autoload/calendar/pixel/114 | 5 + .../calendar.vim/autoload/calendar/pixel/115 | 5 + .../calendar.vim/autoload/calendar/pixel/116 | 5 + .../calendar.vim/autoload/calendar/pixel/117 | 5 + .../calendar.vim/autoload/calendar/pixel/118 | 5 + .../calendar.vim/autoload/calendar/pixel/119 | 5 + .../calendar.vim/autoload/calendar/pixel/120 | 5 + .../calendar.vim/autoload/calendar/pixel/121 | 5 + .../calendar.vim/autoload/calendar/pixel/122 | 5 + .../calendar.vim/autoload/calendar/pixel/123 | 5 + .../calendar.vim/autoload/calendar/pixel/124 | 5 + .../calendar.vim/autoload/calendar/pixel/125 | 5 + .../calendar.vim/autoload/calendar/pixel/126 | 5 + .../calendar.vim/autoload/calendar/pixel/33 | 5 + .../calendar.vim/autoload/calendar/pixel/34 | 5 + .../calendar.vim/autoload/calendar/pixel/35 | 5 + .../calendar.vim/autoload/calendar/pixel/36 | 6 + .../calendar.vim/autoload/calendar/pixel/37 | 5 + .../calendar.vim/autoload/calendar/pixel/38 | 5 + .../calendar.vim/autoload/calendar/pixel/39 | 5 + .../calendar.vim/autoload/calendar/pixel/40 | 5 + .../calendar.vim/autoload/calendar/pixel/41 | 5 + .../calendar.vim/autoload/calendar/pixel/42 | 5 + .../calendar.vim/autoload/calendar/pixel/43 | 5 + .../calendar.vim/autoload/calendar/pixel/44 | 5 + .../calendar.vim/autoload/calendar/pixel/45 | 5 + .../calendar.vim/autoload/calendar/pixel/46 | 5 + .../calendar.vim/autoload/calendar/pixel/47 | 5 + .../calendar.vim/autoload/calendar/pixel/48 | 5 + .../calendar.vim/autoload/calendar/pixel/49 | 5 + .../calendar.vim/autoload/calendar/pixel/50 | 5 + .../calendar.vim/autoload/calendar/pixel/51 | 5 + .../calendar.vim/autoload/calendar/pixel/52 | 5 + .../calendar.vim/autoload/calendar/pixel/53 | 5 + .../calendar.vim/autoload/calendar/pixel/54 | 5 + .../calendar.vim/autoload/calendar/pixel/55 | 5 + .../calendar.vim/autoload/calendar/pixel/56 | 5 + .../calendar.vim/autoload/calendar/pixel/57 | 5 + .../calendar.vim/autoload/calendar/pixel/58 | 5 + .../calendar.vim/autoload/calendar/pixel/59 | 5 + .../calendar.vim/autoload/calendar/pixel/60 | 5 + .../calendar.vim/autoload/calendar/pixel/61 | 5 + .../calendar.vim/autoload/calendar/pixel/62 | 5 + .../calendar.vim/autoload/calendar/pixel/63 | 5 + .../calendar.vim/autoload/calendar/pixel/64 | 5 + .../calendar.vim/autoload/calendar/pixel/65 | 5 + .../calendar.vim/autoload/calendar/pixel/66 | 5 + .../calendar.vim/autoload/calendar/pixel/67 | 5 + .../calendar.vim/autoload/calendar/pixel/68 | 5 + .../calendar.vim/autoload/calendar/pixel/69 | 5 + .../calendar.vim/autoload/calendar/pixel/70 | 5 + .../calendar.vim/autoload/calendar/pixel/71 | 5 + .../calendar.vim/autoload/calendar/pixel/72 | 5 + .../calendar.vim/autoload/calendar/pixel/73 | 5 + .../calendar.vim/autoload/calendar/pixel/74 | 5 + .../calendar.vim/autoload/calendar/pixel/75 | 5 + .../calendar.vim/autoload/calendar/pixel/76 | 5 + .../calendar.vim/autoload/calendar/pixel/77 | 5 + .../calendar.vim/autoload/calendar/pixel/78 | 5 + .../calendar.vim/autoload/calendar/pixel/79 | 5 + .../calendar.vim/autoload/calendar/pixel/80 | 5 + .../calendar.vim/autoload/calendar/pixel/81 | 5 + .../calendar.vim/autoload/calendar/pixel/82 | 5 + .../calendar.vim/autoload/calendar/pixel/83 | 5 + .../calendar.vim/autoload/calendar/pixel/84 | 5 + .../calendar.vim/autoload/calendar/pixel/85 | 5 + .../calendar.vim/autoload/calendar/pixel/86 | 5 + .../calendar.vim/autoload/calendar/pixel/87 | 5 + .../calendar.vim/autoload/calendar/pixel/88 | 5 + .../calendar.vim/autoload/calendar/pixel/89 | 5 + .../calendar.vim/autoload/calendar/pixel/90 | 5 + .../calendar.vim/autoload/calendar/pixel/91 | 5 + .../calendar.vim/autoload/calendar/pixel/92 | 5 + .../calendar.vim/autoload/calendar/pixel/93 | 5 + .../calendar.vim/autoload/calendar/pixel/94 | 5 + .../calendar.vim/autoload/calendar/pixel/95 | 5 + .../calendar.vim/autoload/calendar/pixel/96 | 5 + .../calendar.vim/autoload/calendar/pixel/97 | 5 + .../calendar.vim/autoload/calendar/pixel/98 | 5 + .../calendar.vim/autoload/calendar/pixel/99 | 5 + .../autoload/calendar/setlocal.vim | 61 + .../autoload/calendar/setting.vim | 285 +++++ .../calendar.vim/autoload/calendar/string.vim | 80 ++ .../calendar.vim/autoload/calendar/task.vim | 92 ++ .../autoload/calendar/task/google.vim | 54 + .../autoload/calendar/task/local.vim | 184 +++ .../calendar.vim/autoload/calendar/text.vim | 155 +++ .../calendar.vim/autoload/calendar/time.vim | 241 ++++ .../autoload/calendar/timestamp.vim | 42 + .../calendar.vim/autoload/calendar/util.vim | 117 ++ .../calendar.vim/autoload/calendar/view.vim | 466 +++++++ .../calendar.vim/autoload/calendar/webapi.vim | 384 ++++++ .../calendar.vim/autoload/calendar/week.vim | 62 + bundle/calendar.vim/doc/calendar.txt | 1093 +++++++++++++++++ bundle/calendar.vim/plugin/calendar.vim | 25 + bundle/calendar.vim/syntax/calendar.vim | 103 ++ bundle/calendar.vim/test/cipher.vim | 58 + bundle/calendar.vim/test/day.vim | 132 ++ bundle/calendar.vim/test/pixel.vim | 24 + bundle/calendar.vim/test/week.vim | 106 ++ 178 files changed, 12036 insertions(+), 1 deletion(-) create mode 100644 bundle/calendar.vim/.github/workflows/ci.yaml create mode 100644 bundle/calendar.vim/.gitignore create mode 100644 bundle/calendar.vim/LICENSE create mode 100644 bundle/calendar.vim/README.md create mode 100644 bundle/calendar.vim/autoload/calendar.vim create mode 100644 bundle/calendar.vim/autoload/calendar/argument.vim create mode 100644 bundle/calendar.vim/autoload/calendar/async.vim create mode 100644 bundle/calendar.vim/autoload/calendar/autocmd.vim create mode 100644 bundle/calendar.vim/autoload/calendar/cache.vim create mode 100644 bundle/calendar.vim/autoload/calendar/cipher.vim create mode 100644 bundle/calendar.vim/autoload/calendar/color.vim create mode 100644 bundle/calendar.vim/autoload/calendar/constructor/day.vim create mode 100644 bundle/calendar.vim/autoload/calendar/constructor/day_hybrid.vim create mode 100644 bundle/calendar.vim/autoload/calendar/constructor/month.vim create mode 100644 bundle/calendar.vim/autoload/calendar/constructor/view.vim create mode 100644 bundle/calendar.vim/autoload/calendar/constructor/view_clock.vim create mode 100644 bundle/calendar.vim/autoload/calendar/constructor/view_days.vim create mode 100644 bundle/calendar.vim/autoload/calendar/constructor/view_months.vim create mode 100644 bundle/calendar.vim/autoload/calendar/constructor/view_textbox.vim create mode 100644 bundle/calendar.vim/autoload/calendar/constructor/view_ymd.vim create mode 100644 bundle/calendar.vim/autoload/calendar/constructor/year.vim create mode 100644 bundle/calendar.vim/autoload/calendar/controller.vim create mode 100644 bundle/calendar.vim/autoload/calendar/countcache.vim create mode 100644 bundle/calendar.vim/autoload/calendar/day.vim create mode 100644 bundle/calendar.vim/autoload/calendar/day/austria.vim create mode 100644 bundle/calendar.vim/autoload/calendar/day/austriastyria.vim create mode 100644 bundle/calendar.vim/autoload/calendar/day/british.vim create mode 100644 bundle/calendar.vim/autoload/calendar/day/bulgaria.vim create mode 100644 bundle/calendar.vim/autoload/calendar/day/canada.vim create mode 100644 bundle/calendar.vim/autoload/calendar/day/default.vim create mode 100644 bundle/calendar.vim/autoload/calendar/day/estonia.vim create mode 100644 bundle/calendar.vim/autoload/calendar/day/france.vim create mode 100644 bundle/calendar.vim/autoload/calendar/day/germany.vim create mode 100644 bundle/calendar.vim/autoload/calendar/day/germanyprussia.vim create mode 100644 bundle/calendar.vim/autoload/calendar/day/greece.vim create mode 100644 bundle/calendar.vim/autoload/calendar/day/gregorian.vim create mode 100644 bundle/calendar.vim/autoload/calendar/day/holland.vim create mode 100644 bundle/calendar.vim/autoload/calendar/day/hungary.vim create mode 100644 bundle/calendar.vim/autoload/calendar/day/italy.vim create mode 100644 bundle/calendar.vim/autoload/calendar/day/japan.vim create mode 100644 bundle/calendar.vim/autoload/calendar/day/julian.vim create mode 100644 bundle/calendar.vim/autoload/calendar/day/poland.vim create mode 100644 bundle/calendar.vim/autoload/calendar/day/portugal.vim create mode 100644 bundle/calendar.vim/autoload/calendar/day/russia.vim create mode 100644 bundle/calendar.vim/autoload/calendar/day/spain.vim create mode 100644 bundle/calendar.vim/autoload/calendar/day/turkey.vim create mode 100644 bundle/calendar.vim/autoload/calendar/day/us.vim create mode 100644 bundle/calendar.vim/autoload/calendar/echo.vim create mode 100644 bundle/calendar.vim/autoload/calendar/event.vim create mode 100644 bundle/calendar.vim/autoload/calendar/event/google.vim create mode 100644 bundle/calendar.vim/autoload/calendar/event/local.vim create mode 100644 bundle/calendar.vim/autoload/calendar/google/calendar.vim create mode 100644 bundle/calendar.vim/autoload/calendar/google/client.vim create mode 100644 bundle/calendar.vim/autoload/calendar/google/task.vim create mode 100644 bundle/calendar.vim/autoload/calendar/mapping.vim create mode 100644 bundle/calendar.vim/autoload/calendar/mark.vim create mode 100644 bundle/calendar.vim/autoload/calendar/message.vim create mode 100644 bundle/calendar.vim/autoload/calendar/message/default.vim create mode 100644 bundle/calendar.vim/autoload/calendar/message/en.vim create mode 100644 bundle/calendar.vim/autoload/calendar/message/ja.vim create mode 100644 bundle/calendar.vim/autoload/calendar/model.vim create mode 100644 bundle/calendar.vim/autoload/calendar/pixel.vim create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/100 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/101 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/102 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/103 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/104 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/105 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/106 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/107 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/108 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/109 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/110 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/111 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/112 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/113 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/114 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/115 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/116 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/117 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/118 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/119 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/120 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/121 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/122 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/123 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/124 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/125 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/126 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/33 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/34 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/35 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/36 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/37 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/38 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/39 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/40 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/41 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/42 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/43 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/44 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/45 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/46 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/47 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/48 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/49 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/50 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/51 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/52 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/53 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/54 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/55 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/56 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/57 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/58 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/59 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/60 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/61 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/62 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/63 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/64 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/65 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/66 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/67 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/68 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/69 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/70 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/71 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/72 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/73 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/74 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/75 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/76 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/77 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/78 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/79 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/80 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/81 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/82 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/83 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/84 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/85 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/86 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/87 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/88 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/89 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/90 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/91 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/92 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/93 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/94 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/95 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/96 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/97 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/98 create mode 100644 bundle/calendar.vim/autoload/calendar/pixel/99 create mode 100644 bundle/calendar.vim/autoload/calendar/setlocal.vim create mode 100644 bundle/calendar.vim/autoload/calendar/setting.vim create mode 100644 bundle/calendar.vim/autoload/calendar/string.vim create mode 100644 bundle/calendar.vim/autoload/calendar/task.vim create mode 100644 bundle/calendar.vim/autoload/calendar/task/google.vim create mode 100644 bundle/calendar.vim/autoload/calendar/task/local.vim create mode 100644 bundle/calendar.vim/autoload/calendar/text.vim create mode 100644 bundle/calendar.vim/autoload/calendar/time.vim create mode 100644 bundle/calendar.vim/autoload/calendar/timestamp.vim create mode 100644 bundle/calendar.vim/autoload/calendar/util.vim create mode 100644 bundle/calendar.vim/autoload/calendar/view.vim create mode 100644 bundle/calendar.vim/autoload/calendar/webapi.vim create mode 100644 bundle/calendar.vim/autoload/calendar/week.vim create mode 100644 bundle/calendar.vim/doc/calendar.txt create mode 100644 bundle/calendar.vim/plugin/calendar.vim create mode 100644 bundle/calendar.vim/syntax/calendar.vim create mode 100644 bundle/calendar.vim/test/cipher.vim create mode 100644 bundle/calendar.vim/test/day.vim create mode 100644 bundle/calendar.vim/test/pixel.vim create mode 100644 bundle/calendar.vim/test/week.vim diff --git a/autoload/SpaceVim/layers/tools.vim b/autoload/SpaceVim/layers/tools.vim index bcac6fc58..1565066f8 100644 --- a/autoload/SpaceVim/layers/tools.vim +++ b/autoload/SpaceVim/layers/tools.vim @@ -22,7 +22,7 @@ function! SpaceVim#layers#tools#plugins() abort call add(plugins, ['wsdjeg/vim-cheat', { 'on_cmd' : 'Cheat'}]) call add(plugins, ['wsdjeg/Mysql.vim', { 'on_cmd' : 'SQLGetConnection'}]) call add(plugins, ['wsdjeg/SourceCounter.vim', { 'on_cmd' : 'SourceCounter'}]) - call add(plugins, ['itchyny/calendar.vim', { 'on_cmd' : 'Calendar'}]) + call add(plugins, [g:_spacevim_root_dir . 'bundle/calendar.vim', { 'on_cmd' : 'Calendar'}]) call add(plugins, ['junegunn/limelight.vim', { 'on_cmd' : 'Limelight'}]) call add(plugins, ['junegunn/goyo.vim', { 'on_cmd' : 'Goyo', 'loadconf' : 1}]) call add(plugins, [g:_spacevim_root_dir . 'bundle/vim-bookmarks', diff --git a/bundle/README.md b/bundle/README.md index 6b6c59f02..6f012904a 100644 --- a/bundle/README.md +++ b/bundle/README.md @@ -32,3 +32,4 @@ In `bundle/` directory, there are two kinds of plugins: forked plugins without c - [vim-assembly@2b1994a](https://github.com/wsdjeg/vim-assembly/tree/2b1994a5d23c90651754b4c75750100f63074d8b) - [vim-autohotkey@6bf1e71](https://github.com/wsdjeg/vim-autohotkey/tree/6bf1e718c73cad22caad3ecd8c4db96db05b37f7) - [vim-cmake-syntax@bcc3a97a](https://github.com/pboettch/vim-cmake-syntax/tree/bcc3a97ab934f03e112becd4ce79286793152b47) +- [itchyny/calendar.vim@896360bfd](https://github.com/itchyny/calendar.vim/tree/896360bfd9d5347b2726dd247df2d2cbdb8cf1d6) diff --git a/bundle/calendar.vim/.github/workflows/ci.yaml b/bundle/calendar.vim/.github/workflows/ci.yaml new file mode 100644 index 000000000..e1567017e --- /dev/null +++ b/bundle/calendar.vim/.github/workflows/ci.yaml @@ -0,0 +1,36 @@ +name: CI + +on: + push: + branches: + - master + pull_request: + +jobs: + test: + name: Test + runs-on: ubuntu-latest + strategy: + matrix: + vim: + - v8.2.0000 + - v8.1.0000 + - v8.0.0000 + - v7.4 + steps: + - name: Checkout code + uses: actions/checkout@v3 + - name: Checkout vim-themis + uses: actions/checkout@v3 + with: + repository: thinca/vim-themis + path: vim-themis + - name: Setup Vim + uses: rhysd/action-setup-vim@v1 + id: vim + with: + version: ${{ matrix.vim }} + - name: Test + env: + THEMIS_VIM: ${{ steps.vim.outputs.executable }} + run: ./vim-themis/bin/themis --reporter spec diff --git a/bundle/calendar.vim/.gitignore b/bundle/calendar.vim/.gitignore new file mode 100644 index 000000000..0a56e3fc5 --- /dev/null +++ b/bundle/calendar.vim/.gitignore @@ -0,0 +1 @@ +/doc/tags diff --git a/bundle/calendar.vim/LICENSE b/bundle/calendar.vim/LICENSE new file mode 100644 index 000000000..93dc399e8 --- /dev/null +++ b/bundle/calendar.vim/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2013-2022 itchyny + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/bundle/calendar.vim/README.md b/bundle/calendar.vim/README.md new file mode 100644 index 000000000..4244cfed7 --- /dev/null +++ b/bundle/calendar.vim/README.md @@ -0,0 +1,129 @@ +# A calendar application for Vim +### Vim meets a next generation application + +![calendar.vim](https://raw.githubusercontent.com/wiki/itchyny/calendar.vim/image/image.png) + +Press E key to view the event list, and T key to view the task list. +Also, press ? key to view a quick help. + +![calendar.vim](https://raw.githubusercontent.com/wiki/itchyny/calendar.vim/image/views.png) + +## Basic Usage + + :Calendar + +![calendar.vim](https://raw.githubusercontent.com/wiki/itchyny/calendar.vim/image/image0.png) + + :Calendar 2000 1 1 + +![calendar.vim](https://raw.githubusercontent.com/wiki/itchyny/calendar.vim/image/image1.png) + + :Calendar -view=year + +![calendar.vim](https://raw.githubusercontent.com/wiki/itchyny/calendar.vim/image/image2.png) + + :Calendar -view=year -split=vertical -width=27 + +![calendar.vim](https://raw.githubusercontent.com/wiki/itchyny/calendar.vim/image/image3.png) + + :Calendar -view=year -split=horizontal -position=below -height=12 + +![calendar.vim](https://raw.githubusercontent.com/wiki/itchyny/calendar.vim/image/image4.png) + + :Calendar -first_day=monday + +![calendar.vim](https://raw.githubusercontent.com/wiki/itchyny/calendar.vim/image/image5.png) + + :Calendar -view=clock + +![calendar.vim](https://raw.githubusercontent.com/wiki/itchyny/calendar.vim/image/image6.png) + +You can switch between views with < and > keys. + + + +![calendar.vim](https://raw.githubusercontent.com/wiki/itchyny/calendar.vim/image/frame.png) + +If you have a trouble like the above screenshot, add the following configuration to your vimrc. +```vim +let g:calendar_frame = 'default' +``` + +## Concept +This is a calendar which is ... + +### Comfortable +The key mappings are designed to match the default mappings of Vim. + +### Powerful +The application can be connected to Google Calendar and used in your life. + +### Elegant +The appearance is carefully designed, dropping any unnecessary information. + +### Interesting +You can choose the calendar in Julian calendar or in Gregorian calendar. + +### Useful +To conclude, very useful. + +## Author +itchyny (https://github.com/itchyny) + +## License +This software is released under the MIT License, see LICENSE. + +## Installation +Install with your favorite plugin manager. + +## Google Calendar and Google Task +In order to view and edit calendars on Google Calendar, or task on Google Task, +add the following configurations to your vimrc file. +```vim +let g:calendar_google_calendar = 1 +let g:calendar_google_task = 1 +``` +It requires `wget` or `curl`. + +### Important notice +The default client key is not provided anymore and you will get the **Authorization Error**. +You have to create your own Google API key and use for authentication with the following steps. + +- Create a new project in [GCP](https://cloud.google.com/) and go to [Google APIs](https://console.developers.google.com/apis/). +- Click `ENABLE APIS AND SERVICES` add `Google Calendar API` and `Tasks API`. +- Go to [Google APIs](https://console.developers.google.com/apis/) and click `OAuth consent screen` from the sidebar. + - Choose `External` (Available to any user with a Google Account.) and click `CREATE`. + - Input your favorite name to `Application name`. In the `Scopes for Google APIs` section, click `Add scope` and add `Google Calendar API ../auth/calendar` and `Task API ../auth/tasks`. + - Click `Save` (DO NOT `Submit for verification`). +- Go to the `Credentials` page from the sidebar. + - Create a new API key and restrict key to the two APIs (`Google Calendar API`, `Tasks API`). + - You have the api key. + - Create a new `OAuth client ID`. Select `Desktop application` for the application type. + - You have the client id and client secret. +- Open your terminal and save the credentials. + - `mkdir -p ~/.cache/calendar.vim/ && touch ~/.cache/calendar.vim/credentials.vim` + - `chmod 700 ~/.cache/calendar.vim && chmod 600 ~/.cache/calendar.vim/credentials.vim` + - `vi ~/.cache/calendar.vim/credentials.vim` + - Add the following three lines and save it. Please be sure to keep this file securely. +```vim +let g:calendar_google_api_key = '...' +let g:calendar_google_client_id = '....apps.googleusercontent.com' +let g:calendar_google_client_secret = '...' +``` + - Add `source ~/.cache/calendar.vim/credentials.vim` to your .vimrc. +- Restart Vim and open calendar.vim. You will get the unverified message but click `Advanced` and `Go to your-app (unsafe)`. +- Approve against some confirms (maybe three clicks) and you will get the login code. Copy and paste it into the prompt of calendar.vim. Now you'll be authenticated to your application.. + +## Terms of Use +Under no circumstances we are liable for any damages (including but not limited to damages for loss of business, loss of profits, interruption or the like) arising from use of this software. +This software deals with your events and tasks. +We are not liable for any circumstances; leakage of trade secrets due to the cache files of this software, loss of important events and tasks due to any kind of bugs and absence from important meetings due to any kind of failures of this software. +This software downloads your events from Google Calendar, and your tasks from Google Task. +DO NOT use this software with important events and tasks. +This software downloads your events or tasks to the cache directory. +Please be careful with the cache directory; DO NOT share the directory with any cloud storage softwares. +This software also uploads your events and tasks to Google APIs. +While it uses https, but DO NOT use this software for confidential matters. +This software NEVER uploads your events and tasks to any other server except Google's. +However, if `wget` or `curl` command are replaced with malicious softwares, your events or tasks can be uploaded to other sites. +Please use the official softwares for the commands. diff --git a/bundle/calendar.vim/autoload/calendar.vim b/bundle/calendar.vim/autoload/calendar.vim new file mode 100644 index 000000000..5310899d7 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar.vim @@ -0,0 +1,64 @@ +" ============================================================================= +" Filename: autoload/calendar.vim +" Author: itchyny +" License: MIT License +" Last Change: 2015/03/29 06:35:29. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +" Creates a new buffer and start calendar. +function! calendar#new(args) abort + + " Argument parsing + let [isnewbuffer, command, variables, args] = calendar#argument#parse(a:args) + + " Open a new buffer. + try | silent execute command | catch | return | endtry + + " Clear the previous syntaxes. + silent! call b:calendar.clear() + + " Store the options which are given as the argument. + let b:_calendar = variables + + " Start calendar. + let b:calendar = calendar#controller#new() + " Set time + call b:calendar.set_time(calendar#time#now()) + " Set day and update the buffer. + call b:calendar.go(calendar#argument#day(args, calendar#day#today().get_ymd())) + + " Save b:calendar and b:_calendar. + call calendar#save() + +endfunction + +let s:calendar = {} +let s:_calendar = {} + +" Save b:calendar and b:_calendar. +function! calendar#save() abort + let nr = bufnr('') + if has_key(b:, 'calendar') + let s:calendar[nr] = b:calendar + endif + if has_key(b:, '_calendar') + let s:_calendar[nr] = b:_calendar + endif +endfunction + +" Revive b:calendar and b:_calendar. +function! calendar#revive() abort + let nr = bufnr('') + if !has_key(b:, 'calendar') && has_key(s:calendar, nr) + let b:calendar = get(s:calendar, nr, {}) + endif + if !has_key(b:, '_calendar') && has_key(s:_calendar, nr) + let b:_calendar = get(s:_calendar, nr, {}) + endif +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/argument.vim b/bundle/calendar.vim/autoload/calendar/argument.vim new file mode 100644 index 000000000..0fa7adcf2 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/argument.vim @@ -0,0 +1,320 @@ +" ============================================================================= +" Filename: autoload/calendar/argument.vim +" Author: itchyny +" License: MIT License +" Last Change: 2020/10/17 01:28:50. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +" Deal with argument for the :Calendar command. + +let s:calendars = filter(map(split(globpath(&rtp, 'autoload/calendar/day/**.vim'), '\n'), + \ "substitute(v:val, '.*/\\|.vim', '', 'g')"), + \ 'v:val !~# "^\(default\\|gregorian\\|julian\)$"') +let s:all_value_options = { + \ '-year': [], + \ '-month': [], + \ '-day': [], + \ '-locale': [ 'default', 'en', 'ja' ], + \ '-calendar': ['default', 'gregorian', 'julian'] + sort(s:calendars), + \ '-calendar_candidates': [], + \ '-first_day': [ 'sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday' ], + \ '-time_zone': map(range(-12, 12), 'printf("%+03d00", v:val)'), + \ '-date_endian': [ 'little', 'big', 'middle' ], + \ '-date_separator': [ '/', '-', '.', '" "' ], + \ '-event_start_time_minwidth': [], + \ '-cache_directory': [], + \ '-updatetime': [], + \ '-view': [ 'year', 'month', 'week', 'days', 'day', 'clock', 'event', 'agenda' ], + \ '-frame': [ 'default', 'unicode', 'space', 'unicode_bold', 'unicode_round', 'unicode_double' ], + \ '-position': [ 'here', 'below', 'tab', 'left', 'right', 'topleft', 'topright' ], + \ '-split': [ 'horizontal', 'vertical' ], + \ '-width': [], + \ '-height': [], + \ '-message_prefix': [], + \ '-task_width': [], + \ } +let s:all_novalue_options = [ + \ '-google_calendar', + \ '-google_task', + \ '-date_month_name', + \ '-date_full_month_name', + \ '-cyclic_view', + \ '-task', + \ '-event_start_time', + \ '-skip_event_delete_confirm', + \ '-skip_task_delete_confirm', + \ '-skip_task_clear_completed_confirm', + \ '-yank_deleting', + \ '-task_delete', + \ '-clock_12hour', + \ '-week_number', + \ '-debug' ] +let s:value_options = deepcopy(s:all_value_options) +let s:novalue_options = deepcopy(s:all_novalue_options) +if has_key(g:, 'calendar_hide_options') && type(g:calendar_hide_options) == type([]) && len(g:calendar_hide_options) + for s:k in g:calendar_hide_options + if has_key(s:value_options, s:k) + unlet s:value_options[s:k] + elseif has_key(s:value_options, '-' . s:k) + unlet s:value_options['-' . s:k] + endif + let s:i = index(s:novalue_options, s:k) + if s:i >= 0 + call remove(s:novalue_options, s:i) + endif + let s:i = index(s:novalue_options, '-' . s:k) + if s:i >= 0 + call remove(s:novalue_options, s:i) + endif + endfor + unlet s:k s:i +endif +let s:options = copy(s:novalue_options) + map(keys(deepcopy(s:value_options)), 'v:val . "="') +let s:all_options = copy(s:novalue_options) +for [s:key, s:val] in items(deepcopy(s:value_options)) + call extend(s:all_options, map(s:val, 's:key . "=" . v:val')) +endfor +unlet s:key s:val + +" Completion function. +function! calendar#argument#complete(arglead, cmdline, cursorpos) abort + try + for key in keys(s:value_options) + if a:cmdline =~# key + if a:cmdline =~# key . '=$' + return &wildmode =~# 'full' + \ ? map(copy(s:value_options[key]), 'key . "=" . v:val') + \ : copy(s:value_options[key]) + elseif a:cmdline =~# key . '=\S\+$' + let lead = '^' . substitute(a:cmdline, '.*=', '', '') + let list = filter(copy(s:value_options[key]), 'v:val =~# lead') + if !len(list) + let lead = substitute(a:cmdline, '.*=', '', '') + let list = filter(copy(s:value_options[key]), 'v:val =~# lead') + endif + let arglead = substitute(a:arglead, '=.*', '=', '') + return map(list, 'arglead . v:val') + endif + endif + endfor + let s:options = copy(s:novalue_options) + \ + map(keys(deepcopy(s:value_options)), &wildmode =~# 'full' ? 'v:val' : 'v:val . "="') + let options = copy(s:options) + if a:arglead != '' + let options = sort(filter(copy(s:options), 'stridx(v:val, a:arglead) != -1')) + if len(options) == 0 + let arglead = substitute(a:arglead, '^-\+', '', '') + let options = sort(filter(copy(s:options), 'stridx(v:val, arglead) != -1')) + if len(options) == 0 + try + let argl = substitute(a:arglead, '\(.\)', '.*\1', 'g') . '.*' + let options = sort(filter(copy(s:options), 'v:val =~? argl')) + if len(options) == 0 + let options = sort(filter(copy(s:all_options), 'stridx(v:val, arglead) != -1')) + endif + catch + let options = copy(s:options) + endtry + endif + endif + endif + return sort(filter(options, 'stridx(a:cmdline, v:val) == -1')) + catch + return s:options + endtry +endfunction + +" Splitting the argument. +" This function deals with quotes. +function! calendar#argument#split(args) abort + let args = [''] + let quoteflag = 0 + let quote = '' + for i in range(len(a:args)) + if a:args[i] ==# ' ' + if quoteflag + let args[-1] .= a:args[i] + elseif args[-1] !=# '' + call add(args, '') + endif + elseif (a:args[i] ==# '"' || a:args[i] ==# "'") + if quoteflag && quote ==# a:args[i] + call add(args, '') + let quoteflag = 0 + let quote = '' + elseif quoteflag + let args[-1] .= a:args[i] + else + let quoteflag = 1 + let quote = a:args[i] + endif + else + let args[-1] .= a:args[i] + endif + endfor + return filter(args, 'len(v:val)') +endfunction + +" Option parsing and constructing the buffer-creating command. +function! calendar#argument#parse(args) abort + let args = calendar#argument#split(a:args) + let isnewbuffer = bufname('%') != '' || &l:filetype != '' || &modified + let name = " `='" . calendar#argument#buffername('calendar') . "'`" + let command = 'tabnew' + let commandprefix = '' + let addname = 1 + let ymd = [] + let variables = {} + let [width, height] = [-1, -1] + let [arg_year, flg_year] = [0, 0] + let [arg_month, flg_month] = [0, 0] + let [arg_day, flg_day] = [0, 0] + let flg_ymd = 0 + for arg in args + let novalue = 0 + if arg !~# '=' && arg !~# '^\d\+$' + if index(s:novalue_options, substitute(arg, '!$', '', '')) >= 0 + let bang = arg =~# '!$' + let arg = substitute(arg, '!$', '', '') . '=' . (!bang) + let novalue = 1 + else + let pat = substitute(substitute(arg, '^-', '=', ''), '!$', '', '') . '$' + let opts = filter(copy(s:all_options), 'v:val =~# pat') + let bang = arg =~# '!$' ? '!' : '' + if len(opts) == 1 + let arg = opts[0] . bang + elseif len(opts) > 1 + call calendar#echo#error(calendar#message#get('multiple_argument') . ': ' . join(opts, ', ')) + endif + endif + endif + if arg =~# '=' + let optvar = split(arg, '=') + if len(optvar) == 2 && (has_key(s:value_options, optvar[0]) || novalue) + let option = substitute(optvar[0], '^-\+', '', '') + if option ==# 'position' + if optvar[1] ==# 'here' + let command = 'try | edit' . name . ' | catch | tabnew' . name . ' | endtry' + let addname = 0 + elseif optvar[1] ==# 'here!' + let command = 'edit!' + elseif optvar[1] ==# 'below' + if command ==# 'tabnew' + let command = 'new' + endif + let commandprefix = 'below ' + let isnewbuffer = 1 + elseif index(['left', 'right', 'topleft', 'topright'], optvar[1]) >= 0 + if command ==# 'tabnew' + let command = 'vnew' + endif + let commandprefix = optvar[1] ==# 'left' ? 'leftabove ' + \ : optvar[1] ==# 'right' ? 'rightbelow ' + \ : optvar[1] ==# 'topleft' ? 'topleft ' + \ : optvar[1] ==# 'topright' ? 'botright ' + \ : '' + let isnewbuffer = 1 + elseif optvar[1] ==# 'tab' + let command = 'tabnew' + let isnewbuffer = 1 + endif + elseif option ==# 'split' + if optvar[1] ==# 'horizontal' + let command = 'new' + let isnewbuffer = 1 + elseif optvar[1] ==# 'vertical' + let command = 'vnew' + let isnewbuffer = 1 + endif + elseif option ==# 'width' + let width = optvar[1] + 0 + elseif option ==# 'height' + let height = optvar[1] + 0 + elseif option ==# 'year' + let [arg_year, flg_year, flg_ymd] = [optvar[1], 1, 1] + elseif option ==# 'month' + let [arg_month, flg_month, flg_ymd] = [optvar[1], 1, 1] + elseif option ==# 'day' + let [arg_day, flg_day, flg_ymd] = [optvar[1], 1, 1] + endif + let variables[option] = optvar[1] + endif + elseif arg =~# '^\d\+$' + call add(ymd, arg) + endif + endfor + if command ==# 'new' && height > 0 + let command = height . ' ' . command + elseif command ==# 'vnew' && width > 0 + let command = width . ' ' . command + endif + let cmd1 = 'keepalt '. commandprefix . command . (addname ? name : '') + let cmd2 = 'keepalt edit' . name + let command = 'if isnewbuffer | ' . cmd1 . ' | else | ' . cmd2 . '| endif' + if flg_ymd + let ymd = [arg_year, arg_month, arg_day, flg_year, flg_month, flg_day] + endif + return [isnewbuffer, command, variables, ymd] +endfunction + +" :Calendar [year month day] +" The order is properly dealt with based on the endian setting. +function! calendar#argument#day(day, default) abort + let [y, m, d] = a:default + let l = len(a:day) + let endian = calendar#setting#get('date_endian') + if l == 1 + let day0 = a:day[0] * 1 + if 0 < day0 && day0 < 13 + let [m, d] = [day0, 1] + else + let [y, m, d] = [day0, 1, 1] + endif + elseif l == 2 + let [day0, day1] = [a:day[0] * 1, a:day[1] * 1] + if 0 < day0 && day0 < 13 && 0 < day1 && day1 < 32 && (endian ==# 'big' || endian ==# 'middle') + let [m, d] = [day0, day1] + elseif 0 < day0 && day0 < 32 && 0 < day1 && day1 < 13 && (endian ==# 'little') + let [m, d] = [day1, day0] + elseif 0 < day1 && day1 < 13 && endian ==# 'big' + let [y, m, d] = [day0, day1, 1] + elseif 0 < day0 && day0 < 13 && (endian ==# 'middle' || endian ==# 'little') + let [y, m, d] = [day1, day0, 1] + endif + elseif l == 3 + if endian ==# 'big' + let [y, m, d] = [a:day[0] * 1, a:day[1] * 1, a:day[2] * 1] + elseif endian ==# 'middle' + let [m, d, y] = [a:day[0] * 1, a:day[1] * 1, a:day[2] * 1] + else + let [d, m, y] = [a:day[0] * 1, a:day[1] * 1, a:day[2] * 1] + endif + elseif l == 6 + if a:day[3] | let y = a:day[0] | endif + if a:day[4] | let m = a:day[1] | endif + if a:day[5] | let d = a:day[2] | endif + endif + return calendar#day#new(y, m, d) +endfunction + +" Decision of the buffer name. +function! calendar#argument#buffername(name) abort + let buflist = [] + for i in range(tabpagenr('$')) + call extend(buflist, tabpagebuflist(i + 1)) + endfor + let matcher = 'bufname(v:val) =~# ("\\[" . a:name . "\\( \\d\\+\\)\\?\\]") && index(buflist, v:val) >= 0' + let substituter = 'substitute(bufname(v:val), ".*\\(\\d\\+\\).*", "\\1", "") + 0' + let bufs = map(filter(range(1, bufnr('$')), matcher), substituter) + let i = 0 + while index(bufs, i) >= 0 + let i += 1 + endwhile + return '[' . a:name . (len(bufs) && i ? ' ' . i : '') . ']' +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/async.vim b/bundle/calendar.vim/autoload/calendar/async.vim new file mode 100644 index 000000000..3d256d341 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/async.vim @@ -0,0 +1,122 @@ +" ============================================================================= +" Filename: autoload/calendar/async.vim +" Author: itchyny +" License: MIT License +" Last Change: 2016/11/27 09:07:11. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +let s:use_timer = has('timers') && (v:version >= 800 || has('nvim')) + +" Register a command to be executed asyncronously. Commands are executed using +" - timers if available +" - CursorHold recursion otherwise +" Optional argument: Allow duplication of commands. +function! calendar#async#new(command, ...) abort + if !exists('b:calendar_async') + let b:calendar_async = [] + endif + if len(b:calendar_async) == 0 + if s:use_timer + call timer_start(200, 'calendar#async#call') + execute 'augroup CalendarAsync' . bufnr('') + autocmd! + autocmd BufEnter,WinEnter call calendar#async#call() + augroup END + else + execute 'augroup CalendarAsync' . bufnr('') + autocmd! + autocmd CursorHold call calendar#async#call() + autocmd BufEnter call calendar#async#set_updatetime() + autocmd BufLeave call calendar#async#restore_updatetime() + call calendar#async#set_updatetime() + augroup END + endif + endif + let i = 0 + for [c, num, dup] in b:calendar_async + if c ==# a:command + let i += 1 + if i > 2 * (a:0 && a:1) || !a:0 + return + endif + endif + endfor + call add(b:calendar_async, [a:command, 0, a:0 && a:1]) +endfunction + +" Set updatetime for the calendar buffer. +function! calendar#async#set_updatetime() abort + if !has_key(b:, 'calendar_set_updatetime') || !b:calendar_set_updatetime + let s:updatetime = &updatetime + let &updatetime = calendar#setting#get('updatetime') + endif + let b:calendar_set_updatetime = 1 +endfunction + +" Restore updatetime. +function! calendar#async#restore_updatetime() abort + if has_key(s:, 'updatetime') + let &updatetime = s:updatetime + endif + let b:calendar_set_updatetime = 0 +endfunction + +" Execute the registered commands. +" Ignore the timer argument (optional for CursorHold recursion). +function! calendar#async#call(...) abort + if !exists('b:calendar_async') + return + endif + if !s:use_timer && exists('b:calendar_async_reltime') && has('reltime') + let time = split(split(reltimestr(reltime(b:calendar_async_reltime)))[0], '\.') + if time[0] ==# '0' && len(time[1]) && time[1][0] ==# '0' + silent call feedkeys(mode() ==# 'i' ? "\\" : "g\" . (v:count ? v:count : ''), 'n') + return + endif + endif + let del = [] + let done = {} + let cnt = 0 + let len = len(b:calendar_async) + for i in range(len) + let expression = b:calendar_async[i][0] + if has_key(done, expression) + call add(del, i) + continue + endif + if cnt > 1 && !b:calendar_async[i][2] + continue + endif + let done[expression] = 1 + let cnt += 1 + let ret = eval(expression) + let b:calendar_async[i][1] += 1 + if !ret || b:calendar_async[i][1] > 100 + call add(del, i) + endif + endfor + for i in reverse(del) + call remove(b:calendar_async, i) + endfor + if !s:use_timer && has('reltime') + let b:calendar_async_reltime = reltime() + endif + if len(b:calendar_async) + if s:use_timer + call timer_start(200, 'calendar#async#call') + else + silent call feedkeys(mode() ==# 'i' ? "\\" : "g\" . (v:count ? v:count : ''), 'n') + endif + else + execute 'autocmd! CalendarAsync' . bufnr('') + if !s:use_timer + call calendar#async#restore_updatetime() + endif + endif +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/autocmd.vim b/bundle/calendar.vim/autoload/calendar/autocmd.vim new file mode 100644 index 000000000..dbef4cafd --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/autocmd.vim @@ -0,0 +1,98 @@ +" ============================================================================= +" Filename: autoload/calendar/autocmd.vim +" Author: itchyny +" License: MIT License +" Last Change: 2016/09/20 22:09:40. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +" Autocmd commands. + +function! calendar#autocmd#new() abort + + if &l:filetype ==# 'calendar' + return + endif + + augroup CalendarAutoUpdate + autocmd! + " Update a visible calendar buffer. + autocmd BufEnter,BufWritePost,VimResized * + \ silent! call s:update_visible(expand(''), 0) + autocmd ColorScheme * + \ silent! call s:update_visible(expand(''), 1) + augroup END + + augroup CalendarBuffer + + " When colorscheme is changed, all the calendar syntax groups will be gone. + " So set the filetype forcibly and load the syntax file again. + autocmd ColorScheme + \ silent! call calendar#setlocal#filetype_force() | + \ silent! call calendar#color#refresh_syntax() + + " On entering the buffer, update the calendar. + autocmd BufEnter,WinEnter,ColorScheme + \ silent! call calendar#revive() | + \ silent! call b:calendar.update() + + " On entering the buffer, fire CursorHold to update the clock. + autocmd BufEnter,WinEnter + \ silent! doautocmd CursorHold + + " On resizing the Vim window, check the window size and update if it is changed. + autocmd VimResized,CursorHold + \ silent! call b:calendar.update_if_resized() + + " When the cursor is moved, update the cursor appropriately. + " In mapping.vim, 'gg' is mapped to '(calendar_first_line)' on default. + " However, if we press 'g' and 'g' slowly, '(calendar_first_line)' will + " not be triggered. Pressing 'g' and '$' slowly also causes the same situation. + " To avoid this, check the cursor position on CursorMoved and move the cursor + " to the proper position. + autocmd CursorMoved + \ silent! call b:calendar.cursor_moved() + + augroup END + +endfunction + +" Search the calendar buffer and updates. +function! s:update_visible(bufnr, is_colorscheme) abort + try + let nr = -1 + let newnr = str2nr(a:bufnr) + if bufname(newnr) ==# '[Command Line]' + return + endif + for buf in tabpagebuflist() + if type(getbufvar(buf, 'calendar')) == type({}) && buf != newnr + let nr = buf + break + endif + endfor + if nr == -1 | return | endif + let winnr = bufwinnr(nr) + let newbuf = bufwinnr(str2nr(a:bufnr)) + let currentbuf = bufwinnr(bufnr('%')) + noautocmd execute winnr 'wincmd w' + if a:is_colorscheme + silent! call calendar#setlocal#filetype_force() + silent! call calendar#color#refresh_syntax() + endif + silent! call b:calendar.update_force() + if winnr != newbuf && newbuf != -1 + call cursor(1, 1) + noautocmd execute newbuf 'wincmd w' + elseif winnr != currentbuf && currentbuf != -1 + call cursor(1, 1) + noautocmd execute currentbuf 'wincmd w' + endif + catch + endtry +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/cache.vim b/bundle/calendar.vim/autoload/calendar/cache.vim new file mode 100644 index 000000000..d4a9b28e1 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/cache.vim @@ -0,0 +1,236 @@ +" ============================================================================= +" Filename: autoload/calendar/cache.vim +" Author: itchyny +" License: MIT License +" Last Change: 2020/11/20 00:09:42. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +" Cache object. +function! calendar#cache#new(...) abort + let self = copy(s:self) + let self.subpath = a:0 ? a:1 : '' + let self.subpath .= len(self.subpath) && self.subpath[len(self.subpath) - 1] !~ '^[/\\]$' ? '/' : '' + call s:setfperm_dir(self.dir()) + return self +endfunction + +function! calendar#cache#clear() abort + for path in s:clearpath + call calendar#util#rmdir(path, 'rf') + endfor +endfunction + +let s:clearpath = [] + +augroup CalendarCache + autocmd! + autocmd VimLeavePre * call calendar#cache#clear() +augroup END + +let s:self = {} + +function! s:self.new(...) dict abort + return calendar#cache#new(self.subpath . (a:0 ? self.escape(a:1) : '')) +endfunction + +function! s:self.escape(key) dict abort + return substitute(a:key, '[^a-zA-Z0-9_.-]', '\=printf("%%%02X",char2nr(submatch(0)))', 'g') +endfunction + +if has('win32') + function! s:self.dir() dict abort + return substitute(substitute(s:expand_homedir(calendar#setting#get('cache_directory')), '[/\\]$', '', '') . '/' . self.subpath, '/', '\', 'g') + endfunction +else + function! s:self.dir() dict abort + return substitute(s:expand_homedir(calendar#setting#get('cache_directory')), '[/\\]$', '', '') . '/' . self.subpath + endfunction +endif + +function! s:expand_homedir(path) abort + if a:path !~# '^[~]/' + return a:path + endif + return expand('~') . a:path[1:] +endfunction + +function! s:self.path(key) dict abort + return self.dir() . self.escape(a:key) +endfunction + +function! s:self.rmdir_on_exit() dict abort + call add(s:clearpath, self.dir()) +endfunction + +function! s:self.check_dir(...) dict abort + let dir = self.dir() + if !get(a:000, 0) + return !isdirectory(dir) + endif + if !isdirectory(dir) + try + if exists('*mkdir') + call mkdir(dir, 'p') + else + call calendar#util#system('mkdir -p ' . shellescape(dir)) + endif + call s:setfperm(dir) + catch + endtry + endif + if !isdirectory(dir) + call calendar#echo#error(calendar#message#get('mkdir_fail') . ': ' . dir) + return 1 + endif +endfunction + +function! s:self.save(key, val) dict abort + if self.check_dir(1) + return 1 + endif + let path = self.path(a:key) + if filereadable(path) && !filewritable(path) + call calendar#echo#error(calendar#message#get('cache_file_unwritable') . ': ' . path) + return 1 + endif + try + call writefile(calendar#cache#string(a:val), path) + call s:setfperm_file(path) + catch + call calendar#echo#error(calendar#message#get('cache_write_fail') . ': ' . path) + return 1 + endtry +endfunction + +function! s:self.get(key) dict abort + if self.check_dir() + return 1 + endif + let path = self.path(a:key) + if filereadable(path) + call s:setfperm_file(path) + let result = readfile(path) + try + if len(result) + if exists('*js_decode') && has('patch-8.0.0216') + return js_decode(len(result) > 1 ? join(result, '') : result[0]) + endif + sandbox return eval(join(result, '')) + else + return 1 + endif + catch + return 1 + endtry + else + return 1 + endif +endfunction + +function! s:self.get_raw(key) dict abort + if self.check_dir() + return 1 + endif + let path = self.path(a:key) + if filereadable(path) + call s:setfperm_file(path) + return readfile(path) + else + return 1 + endif +endfunction + +function! s:self.delete(key) dict abort + if self.check_dir() + return 1 + endif + let path = self.path(a:key) + return delete(path) +endfunction + +function! s:self.clear() dict abort + call calendar#util#rmdir(self.dir(), 'rf') +endfunction + +if exists('*json_encode') + function! calendar#cache#string(v) abort + return [json_encode(a:v)] + endfunction +else + " string() with making newlines and indents properly. + function! calendar#cache#string(v, ...) abort + let r = [] + let f = 1 + let s = a:0 ? a:1 : '' + if type(a:v) == type([]) + call add(r, '[ ') + let s .= ' ' + for i in range(len(a:v)) + call add(r, s . string(a:v[i]) . ',') + endfor + if r[-1][len(r[-1]) - 1] ==# ',' + let r[-1] = r[-1][:-2] + endif + call add(r, ' ]') + elseif type(a:v) == type({}) + call add(r, '{ ') + let s .= ' ' + for k in keys(a:v) + if type(a:v[k]) == type({}) || type(a:v[k]) == type([]) && len(a:v[k]) > 2 + let result = calendar#cache#string(a:v[k], s . repeat(' ', len(string(k)) + 2)) + let result[-1] .= ',' + call add(r, s . string(k) . ': ' . result[0]) + call remove(result, 0) + call extend(r, result) + else + call add(r, s . string(k) . ': ' . string(a:v[k]) . ',') + endif + endfor + if r[-1][len(r[-1]) - 1] ==# ',' + let r[-1] = r[-1][:-2] + endif + call add(r, ' }') + else + call add(r, s . string(a:v)) + let f = 0 + endif + if f + if len(r[1]) > len(s) + 1 + let r[1] = r[1][len(s):] + endif + let r[0] .= r[1] + call remove(r, 1) + if len(r) > 1 + let r[-2] .= r[-1] + call remove(r, -1) + endif + endif + return r + endfunction +endif + +if exists('*getfperm') && exists('*setfperm') + function! s:setfperm_dir(dir) abort + let expected = 'rwx------' + if getfperm(a:dir) !=# expected + call setfperm(a:dir, expected) + endif + endfunction + function! s:setfperm_file(path) abort + let expected = 'rw-------' + if getfperm(a:path) !=# expected + call setfperm(a:path, expected) + endif + endfunction +else + function! s:setfperm_dir(dir) abort + endfunction + function! s:setfperm_file(path) abort + endfunction +endif + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/cipher.vim b/bundle/calendar.vim/autoload/calendar/cipher.vim new file mode 100644 index 000000000..85cc176e4 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/cipher.vim @@ -0,0 +1,58 @@ +" ============================================================================= +" Filename: autoload/calendar/cipher.vim +" Author: itchyny +" License: MIT License +" Last Change: 2015/03/29 06:25:35. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +" Caesar cipher functions. +" This DOES NOT encrypt a message into a code difficult to revive the +" original message. This module is used for the client id and api key of +" the default google client in setting.vim, because I don't want to save +" the keys in raw strings, which can be extracted easily. +" Reference: http://en.wikipedia.org/wiki/Caesar_cipher + +function! calendar#cipher#cipher(val, num) abort + if type(a:val) == type('') + return s:cipher(a:val, a:num) + elseif type(a:val) == type(0) + return s:cipher(a:val . '', a:num) + elseif type(a:val) == type([]) + return map(a:val, 'calendar#cipher#cipher(v:val, a:num)') + elseif type(a:val) == type({}) + let ret = {} + for key in keys(a:val) + let ret[key] = calendar#cipher#cipher(a:val[key], a:num) + endfor + return ret + endif +endfunction + +function! calendar#cipher#decipher(val, num) abort + return calendar#cipher#cipher(a:val, - a:num) +endfunction + +function! s:cipher(str, num) abort + let ret = '' + let r = range(len(a:str)) + for i in r + let nr = char2nr(a:str[i]) + if 32 <= nr && nr < 127 + let nr = nr + a:num - 32 + while nr < 0 + let nr += 127 - 32 + endwhile + let nr = nr % (127 - 32) + 32 + let ret .= nr2char(nr) + else + return '' + endif + endfor + return ret +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/color.vim b/bundle/calendar.vim/autoload/calendar/color.vim new file mode 100644 index 000000000..75cac9b63 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/color.vim @@ -0,0 +1,490 @@ +" ============================================================================= +" Filename: autoload/calendar/color.vim +" Author: itchyny +" License: MIT License +" Last Change: 2019/07/30 22:37:29. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +" Color utility + +let s:is_gui = has('gui_running') || (has('termguicolors') && &termguicolors) +let s:is_cterm = !s:is_gui +let s:is_win32cui = has('win32') && !s:is_gui +let s:term = s:is_gui ? 'gui' : 'cterm' +let s:is_dark = -1 +let s:colors_name = '' +let s:background = '' + +" &background is not useful on non-GUI environment when colorscheme executes :highlight Normal ctermbg=23X. +" ref: syntax.c /set_option_value +function! calendar#color#is_dark() abort + if s:is_dark >= 0 && s:colors_name ==# get(g:, 'colors_name', '') && s:background ==# &background + return s:is_dark + endif + let s:colors_name = get(g:, 'colors_name', '') + let s:background = &background + if s:is_gui + let s:is_dark = &background ==# 'dark' + return s:is_dark + endif + let bg_color = synIDattr(synIDtrans(hlID('Normal')), 'bg', s:term) + if bg_color !=# '' + let [r, g, b] = calendar#color#nr_rgb(bg_color) + let s:is_dark = r + g + b < 7 || 232 <= bg_color && bg_color <= 243 + return s:is_dark + endif + let fg_color = synIDattr(synIDtrans(hlID('Normal')), 'fg', s:term) + if fg_color !=# '' + let [r, g, b] = calendar#color#nr_rgb(fg_color) + let s:is_dark = r + g + b > 8 || 244 <= fg_color + return s:is_dark + endif + let bg_color = synIDattr(synIDtrans(hlID('Normal')), 'bg', 'gui') + if bg_color =~# '^#......$' + let s:is_dark = s:is_dark_color(bg_color) + return s:is_dark + endif + let fg_color = synIDattr(synIDtrans(hlID('Normal')), 'fg', 'gui') + if fg_color =~# '^#......$' + let s:is_dark = s:is_light_color(fg_color) + return s:is_dark + endif + let s:is_dark = &background ==# 'dark' + return s:is_dark +endfunction + +function! calendar#color#new_syntax(id, fg, bg) abort + if has_key(b:, 'calendar') + if !has_key(b:calendar, 'syntaxnames') + let b:calendar.syntaxnames = [] + endif + let syntaxnames = b:calendar.syntaxnames + if !has_key(b:calendar, 'syntax') + let b:calendar.syntax = {} + endif + let b:calendar.syntax[a:id] = [a:id, a:fg, a:bg] + else + let syntaxnames = [] + endif + let name = s:shorten(substitute(a:id, '[^a-zA-Z0-9]', '', 'g')) + if len(name) && len(a:fg) && len(a:bg) + if index(syntaxnames, name) >= 0 + return name + endif + let flg = 0 + let is_dark = calendar#color#is_dark() + if is_dark && s:is_dark_color(a:fg) || !is_dark && s:is_light_color(a:fg) + let flg = 1 + let [fg, bg] = [a:bg, ''] + else + let [fg, bg] = [a:fg, a:bg] + endif + let cuifg = calendar#color#convert(fg) + let cuibg = calendar#color#convert(bg) + if flg + let _bg = bg + let _cuibg = cuibg + else + let _bg = calendar#color#whiten(bg) + let _cuibg = calendar#color#convert(_bg) + endif + if cuifg >= 0 + if index(syntaxnames, name) < 0 + call add(syntaxnames, name) + endif + if _cuibg >= 0 + exec 'highlight Calendar' . name . ' ctermfg=' . cuifg . ' ctermbg=' . _cuibg . ' guifg=' . fg . ' guibg=' . _bg + else + exec 'highlight Calendar' . name . ' ctermfg=' . cuifg . ' guifg=' . fg + endif + let select_bg = s:select_color() + if type(select_bg) == type('') || select_bg >= 0 + let nameselect = name . 'Select' + if index(syntaxnames, nameselect) < 0 + call add(syntaxnames, nameselect) + endif + if s:is_gui + exec 'highlight Calendar' . nameselect . ' guifg=' . fg . ' guibg=' . (flg ? select_bg : bg) + else + exec 'highlight Calendar' . nameselect . ' ctermfg=' . cuifg . ' ctermbg=' . (flg ? select_bg : cuibg) + endif + endif + endif + return name + endif + return '' +endfunction + +function! calendar#color#refresh_syntax() abort + if !has_key(b:, 'calendar') || !has_key(b:calendar, 'syntaxnames') || !has_key(b:calendar, 'syntax') + return + endif + let b:calendar.syntaxnames = [] + for [id, fg, bg] in values(b:calendar.syntax) + call calendar#color#new_syntax(id, fg, bg) + endfor +endfunction + +function! calendar#color#convert(rgb) abort + let rgb = map(matchlist(a:rgb, '#\(..\)\(..\)\(..\)')[1:3], '0 + ("0x".v:val)') + if len(rgb) == 0 + return -1 + endif + if rgb[0] == 0xc0 && rgb[1] == 0xc0 && rgb[2] == 0xc0 + return 7 + elseif rgb[0] == 0x80 && rgb[1] == 0x80 && rgb[2] == 0x80 + return 8 + elseif s:is_win32cui + if rgb[0] > 127 && rgb[1] > 127 && rgb[2] > 127 + let min = 0 + for r in rgb + let min = min([min, r]) + endfor + let rgb[index(rgb, min)] -= 127 + endif + let newrgb = [rgb[0] > 0xa0 ? 4 : 0, rgb[1] > 0xa0 ? 2 : 0, rgb[2] > 0xa0 ? 1 : 0] + return newrgb[0] + newrgb[1] + newrgb[2] + (rgb[0] > 196 || rgb[1] > 196 || rgb[2] > 196) * 8 + elseif (rgb[0] == 0x80 || rgb[0] == 0x00) && (rgb[1] == 0x80 || rgb[1] == 0x00) && (rgb[2] == 0x80 || rgb[2] == 0x00) + return (rgb[0] / 0x80) + (rgb[1] / 0x80) * 2 + (rgb[1] / 0x80) * 4 + elseif (rgb[0]-rgb[1] >= 0 ? rgb[0]-rgb[1] : -(rgb[0]-rgb[1])) < 3 + \ && (rgb[1]-rgb[2] >= 0 ? rgb[1]-rgb[2] : -(rgb[1]-rgb[2])) < 3 + \ && (rgb[2]-rgb[0] >= 0 ? rgb[2]-rgb[0] : -(rgb[2]-rgb[0])) < 3 + return s:black((rgb[0] + rgb[1] + rgb[2]) / 3) + else + return 16 + ((s:nr(rgb[0]) * 6) + s:nr(rgb[1])) * 6 + s:nr(rgb[2]) + endif +endfunction + +function! calendar#color#whiten(rgb) abort + let rgb = map(matchlist(a:rgb, '#\(..\)\(..\)\(..\)')[1:3], '0 + ("0x".v:val)') + if len(rgb) == 0 + return -1 + endif + return printf('#%02x%02x%02x', min([rgb[0] + 0x36, 0xff]), min([rgb[1] + 0x36, 0xff]), min([rgb[2] + 0x36, 0xff])) +endfunction + +function! s:black(x) abort + if a:x < 0x04 + return 16 + elseif a:x > 0xf4 + return 231 + elseif index([0x00, 0x5f, 0x87, 0xaf, 0xdf, 0xff], a:x) >= 0 + let l = a:x / 0x30 + return ((l * 6) + l) * 6 + l + 16 + else + return 232 + (a:x < 8 ? 0 : a:x < 0x60 ? (a:x-8)/10 : a:x < 0x76 ? (a:x-0x60)/6+9 : (a:x-8)/10) + endif +endfunction + +function! s:nr(x) abort + return a:x < 0x2f ? 0 : a:x < 0x73 ? 1 : a:x < 0x9b ? 2 : a:x < 0xc7 ? 3 : a:x < 0xef ? 4 : 5 +endfunction + +function! s:is_dark_color(rgb) abort + let rgb = map(matchlist(a:rgb, '#\(..\)\(..\)\(..\)')[1:3], '0 + ("0x".v:val)') + return len(rgb) == 3 && rgb[0] < 0x2f && rgb[1] < 0x2f && rgb[2] < 0x2f +endfunction + +function! s:is_light_color(rgb) abort + let rgb = map(matchlist(a:rgb, '#\(..\)\(..\)\(..\)')[1:3], '0 + ("0x".v:val)') + return len(rgb) == 3 && rgb[0] > 0xd0 && rgb[1] > 0xd0 && rgb[2] > 0xd0 +endfunction + +function! calendar#color#gui_color() abort + if has_key(s:, '_gui_color') | return s:_gui_color | endif + let s:_gui_color = { + \ 'black' : '#000000', + \ 'white' : '#ffffff', + \ + \ 'darkestgreen' : '#005f00', + \ 'darkgreen' : '#008700', + \ 'mediumgreen' : '#5faf00', + \ 'brightgreen' : '#afdf00', + \ + \ 'darkestcyan' : '#005f5f', + \ 'mediumcyan' : '#87dfff', + \ + \ 'darkestblue' : '#005f87', + \ 'darkblue' : '#0087af', + \ + \ 'darkestred' : '#5f0000', + \ 'darkred' : '#870000', + \ 'mediumred' : '#af0000', + \ 'brightred' : '#df0000', + \ 'brightestred' : '#ff0000', + \ + \ 'darkestpurple' : '#5f00af', + \ 'mediumpurple' : '#875fdf', + \ 'brightpurple' : '#dfdfff', + \ + \ 'brightorange' : '#ff8700', + \ 'brightestorange': '#ffaf00', + \ + \ 'gray0' : '#121212', + \ 'gray1' : '#262626', + \ 'gray2' : '#303030', + \ 'gray3' : '#4e4e4e', + \ 'gray4' : '#585858', + \ 'gray5' : '#606060', + \ 'gray6' : '#808080', + \ 'gray7' : '#8a8a8a', + \ 'gray8' : '#9e9e9e', + \ 'gray9' : '#bcbcbc', + \ 'gray10' : '#d0d0d0', + \ + \ 'yellow' : '#b58900', + \ 'orange' : '#cb4b16', + \ 'red' : '#dc322f', + \ 'magenta' : '#d33682', + \ 'violet' : '#6c71c4', + \ 'blue' : '#268bd2', + \ 'cyan' : '#2aa198', + \ 'green' : '#859900', + \ } + return s:_gui_color +endfunction + +function! calendar#color#to_256color(nr, fg) abort + if a:nr == 0 || a:nr == 16 + return 232 + elseif a:nr == 15 || a:nr == 231 + return 255 + elseif a:nr < 16 + if a:fg + return calendar#color#is_dark() ? 255 : 232 + else + return calendar#color#is_dark() ? 232 : 255 + endif + else + return a:nr + endif +endfunction + +function! calendar#color#fg_color(syntax_name) abort + let color = synIDattr(synIDtrans(hlID(a:syntax_name)), 'fg', s:term) + return s:is_gui ? color : calendar#color#to_256color((len(color) == 0 ? -1 : color) + 0, 1) +endfunction + +function! calendar#color#bg_color(syntax_name) abort + let color = synIDattr(synIDtrans(hlID(a:syntax_name)), 'bg', s:term) + return s:is_gui ? color : calendar#color#to_256color((len(color) == 0 ? -1 : color) + 0, 0) +endfunction + +function! calendar#color#normal_fg_color() abort + if s:is_win32cui + if calendar#color#is_dark() + return 15 + else + return 0 + endif + endif + let fg_color = calendar#color#fg_color('Normal') + if s:is_cterm && type(fg_color) == type(0) && fg_color < 0 + if calendar#color#is_dark() + return 255 + else + return 232 + endif + endif + return fg_color +endfunction + +function! calendar#color#normal_bg_color() abort + if s:is_win32cui + if calendar#color#is_dark() + return 0 + else + return 15 + endif + endif + let bg_color = calendar#color#bg_color('Normal') + if s:is_cterm && type(bg_color) == type(0) && bg_color < 0 + if calendar#color#is_dark() + return 232 + else + return 255 + endif + endif + return bg_color +endfunction + +function! calendar#color#comment_fg_color() abort + if s:is_win32cui + return 7 + endif + let fg_color = calendar#color#fg_color('Comment') + if s:is_cterm && type(fg_color) == type(0) && fg_color < 0 + if calendar#color#is_dark() + return 244 + else + return 243 + endif + endif + return fg_color +endfunction + +function! calendar#color#comment_bg_color() abort + if s:is_win32cui + if calendar#color#is_dark() + return 0 + else + return 15 + endif + endif + let bg_color = calendar#color#bg_color('Comment') + if s:is_cterm && type(bg_color) == type(0) && bg_color < 0 + if calendar#color#is_dark() + return 232 + else + return 255 + endif + endif + return bg_color +endfunction + +function! calendar#color#nr_rgb(nr) abort + let x = a:nr * 1 + if x < 8 + let [b, rg] = [x / 4, x % 4] + let [g, r] = [rg / 2, rg % 2] + return [r * 3, g * 3, b * 3] + elseif x == 8 + return [4, 4, 4] + elseif x < 16 + let y = x - 8 + let [b, rg] = [y / 4, y % 4] + let [g, r] = [rg / 2, rg % 2] + return [r * 5, g * 5, b * 5] + elseif x < 232 + let y = x - 16 + let [rg, b] = [y / 6, y % 6] + let [r, g] = [rg / 6, rg % 6] + return [r, g, b] + else + let k = (x - 232) * 5 / 23 + return [k, k, k] + endif +endfunction + +if s:is_win32cui + + function! calendar#color#gen_color(fg, bg, weightfg, weightbg) abort + return a:weightfg > a:weightbg ? a:fg : a:bg + endfunction + +elseif s:is_cterm + + function! calendar#color#gen_color(fg, bg, weightfg, weightbg) abort + let fg = a:fg < 0 ? (s:is_dark ? 255 : 232) : a:fg + let bg = a:bg < 0 ? (s:is_dark ? 232 : 255) : a:bg + let fg_rgb = calendar#color#nr_rgb(fg) + let bg_rgb = calendar#color#nr_rgb(bg) + if fg > 231 && bg > 231 + let color = (fg * a:weightfg + bg * a:weightbg) / (a:weightfg + a:weightbg) + elseif fg < 16 || bg < 16 + let color = a:weightfg > a:weightbg ? fg : bg + else + let color_rgb = map([0, 1, 2], '(fg_rgb[v:val] * a:weightfg + bg_rgb[v:val] * a:weightbg) / (a:weightfg + a:weightbg)') + let color = ((color_rgb[0] * 6 + color_rgb[1]) * 6 + color_rgb[2]) + 16 + endif + return color + endfunction + + function! calendar#color#select_rgb(color, rgb, weight) abort + let c = calendar#color#nr_rgb(a:color < 0 ? (s:is_dark ? 255 : 232) : a:color) + let cc = max([(c[0] + c[1] + c[2]) / 3, 5]) + let colors = [cc / a:weight, cc / a:weight, cc / a:weight] + let colors[a:rgb] = cc + let color = ((colors[0] * 6 + colors[1]) * 6 + colors[2]) + 16 + return color + endfunction + +else + + function! calendar#color#gen_color(fg, bg, weightfg, weightbg) abort + let fg_rgb = map(matchlist(a:fg[0] == '#' ? a:fg : get(calendar#color#gui_color(), a:fg, ''), '#\(..\)\(..\)\(..\)')[1:3], '("0x".v:val) + 0') + let bg_rgb = map(matchlist(a:bg[0] == '#' ? a:bg : get(calendar#color#gui_color(), a:bg, ''), '#\(..\)\(..\)\(..\)')[1:3], '("0x".v:val) + 0') + if len(fg_rgb) != 3 | let fg_rgb = s:is_dark ? [0xe4, 0xe4, 0xe4] : [0x12, 0x12, 0x12] | endif + if len(bg_rgb) != 3 | let bg_rgb = s:is_dark ? [0x12, 0x12, 0x12] : [0xe4, 0xe4, 0xe4] | endif + let color_rgb = map(map([0, 1, 2], '(fg_rgb[v:val] * a:weightfg + bg_rgb[v:val] * a:weightbg) / (a:weightfg + a:weightbg)'), 'v:val < 0 ? 0 : v:val > 0xff ? 0xff : v:val') + let color = printf('0x%02x%02x%02x', color_rgb[0], color_rgb[1], color_rgb[2]) + 0 + if color < 0 || 0xffffff < color | let color = s:is_dark ? 0x3a3a3a : 0xbcbcbc | endif + return printf('#%06x', color) + endfunction + + function! calendar#color#select_rgb(color, rgb) abort + let c = map(matchlist(a:color[0] == '#' ? a:color : get(calendar#color#gui_color(), a:color, ''), '#\(..\)\(..\)\(..\)')[1:3], '("0x".v:val) + 0') + if len(c) != 3 | let c = s:is_dark ? [0xe4, 0xe4, 0xe4] : [0x12, 0x12, 0x12] | endif + let cc = max([(c[0] + c[1] + c[2]) / 3, 0x6f]) + let color = printf('0x%02x%02x%02x', a:rgb % 2 ? cc : cc / 9, (a:rgb / 2) % 2 ? cc : cc / 9, (a:rgb / 4) % 2 ? cc : cc / 9) + 0 + if color < 0 || 0xffffff < color | let color = s:is_dark ? 0x3a3a3a : 0xbcbcbc | endif + return printf('#%06x', color) + endfunction + +endif + +function! calendar#color#colors() abort + return [ + \ '#16a765', + \ '#4986e7', + \ '#fad165', + \ '#b99aff', + \ '#f83a22', + \ '#9fe1e7', + \ '#ffad46', + \ '#9a9cff', + \ '#f691b2', + \ '#9fe1e7', + \ '#92e1c0', + \ '#ac725e', + \ '#ff7537', + \ '#b3dc6c', + \ '#9fc6e7', + \ '#fbe983', + \ '#d06b64', + \ ] +endfunction + +function! calendar#color#syntax(name, fg, bg, attr) abort + let term = len(a:attr) ? ' term=' . a:attr . ' cterm=' . a:attr . ' gui=' . a:attr : '' + if s:is_gui + let fg = len(a:fg) ? ' guifg=' . a:fg : '' + let bg = len(a:bg) ? ' guibg=' . a:bg : '' + else + let fg = len(a:fg) ? ' ctermfg=' . a:fg : '' + let bg = len(a:bg) ? ' ctermbg=' . a:bg : '' + endif + exec 'highlight Calendar' . a:name . term . fg . bg +endfunction + +let s:_select_color = {} +function! s:select_color() abort + let key = get(g:, 'colors_name', '') . &background + if has_key(s:_select_color, key) + return s:_select_color[key] + endif + let fg_color = calendar#color#normal_fg_color() + let bg_color = calendar#color#normal_bg_color() + let select_color = calendar#color#gen_color(fg_color, bg_color, 1, 4) + if s:is_win32cui + let select_color = s:is_dark ? 8 : 7 + endif + let s:_select_color[key] = select_color + return select_color +endfunction + +let s:num = 0 +let s:nums = {} +function! s:shorten(name) abort + let name = matchstr(a:name, '...') + let name = name ==# '' ? a:name : name + let s:num = (s:num + 1) % 26 + let s:nums[a:name] = get(s:nums, a:name, s:num) + return name . 'abcdefghijklmnopqrstuvwxyz'[s:nums[a:name]] +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/constructor/day.vim b/bundle/calendar.vim/autoload/calendar/constructor/day.vim new file mode 100644 index 000000000..34fc5abd8 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/constructor/day.vim @@ -0,0 +1,155 @@ +" ============================================================================= +" Filename: autoload/calendar/constructor/day.vim +" Author: itchyny +" License: MIT License +" Last Change: 2017/05/07 22:22:26. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +function! calendar#constructor#day#new(instance) abort + let constructor = extend({ 'instance': a:instance }, s:constructor) + let constructor.month_constructor = calendar#constructor#month#new(constructor) + let constructor.year_constructor = calendar#constructor#year#new(constructor) + return constructor +endfunction + +let s:constructor = {} + +function! s:constructor.new(y, m, d) dict abort + return extend(self.instance.new(a:y, a:m, a:d), { 'constructor': self }) +endfunction + +" Modified Julian Day +" Reference: http://en.wikipedia.org/wiki/Julian_day +function! s:constructor.new_mjd(mjd) dict abort + return extend(extend(copy(s:instance), self.instance), { 'mjd': a:mjd, 'constructor': self }) +endfunction + +let s:instance = {} + +function! s:div(x, y) abort + return a:x/a:y-((a:x<0)&&(a:x%a:y)) +endfunction + +function! s:instance.add(diff) dict abort + return self.new_mjd(self.mjd + a:diff) +endfunction + +function! s:instance.add_month(diff) dict abort + let [y, m, d] = self.get_ymd() + let m += a:diff - 1 + let y += s:div(m, 12) + let m -= 12 * s:div(m, 12) + let m += 1 + let new_day = self.new(y, m, d) + let new_month = self.constructor.month_constructor.new(y, m) + if !new_day.is_valid() + if new_day.sub(new_month.head_day()) > 0 + while !(new_day.eq_month(new_month.head_day())) + let new_day = new_day.add(-1) + endwhile + else + while !(new_day.eq_month(new_month.head_day())) + let new_day = new_day.add(1) + endwhile + endif + endif + return new_day +endfunction + +function! s:instance.add_year(diff) dict abort + return self.add_month(a:diff * 12) +endfunction + +function! s:instance.sub(day) dict abort + return self.mjd - a:day.mjd +endfunction + +function! s:instance.week() dict abort + if has_key(self, '_week') | return self._week | endif + let m = self.mjd + 3 + let self._week = m % 7 + 7 * ((m < 0) && (m % 7)) + return self._week +endfunction + +function! s:instance.today() dict abort + return self.new_mjd(calendar#day#today_mjd()) +endfunction + +function! s:instance.eq(day) dict abort + return self.mjd == a:day.mjd +endfunction + +function! s:instance.eq_month(day) dict abort + return self.month().eq(a:day.month()) +endfunction + +function! s:instance.eq_year(day) dict abort + return self.year().eq(a:day.year()) +endfunction + +function! s:instance.eq_week(day) dict abort + return self.week() == a:day.week() +endfunction + +function! s:instance.is_sunday() dict abort + return self.week() == 0 +endfunction + +function! s:instance.is_monday() dict abort + return self.week() == 1 +endfunction + +function! s:instance.is_tuesday() dict abort + return self.week() == 2 +endfunction + +function! s:instance.is_wednesday() dict abort + return self.week() == 3 +endfunction + +function! s:instance.is_thursday() dict abort + return self.week() == 4 +endfunction + +function! s:instance.is_friday() dict abort + return self.week() == 5 +endfunction + +function! s:instance.is_saturday() dict abort + return self.week() == 6 +endfunction + +function! s:instance.is_valid() dict abort + return !has_key(self, '_ymd') || self._ymd == self.get_ymd() +endfunction + +function! s:instance.get_year() dict abort + return self.get_ymd()[0] +endfunction + +function! s:instance.get_month() dict abort + return self.get_ymd()[1] +endfunction + +function! s:instance.get_day() dict abort + return self.get_ymd()[2] +endfunction + +function! s:instance.month() dict abort + if has_key(self, '_month') | return self._month | endif + let [y, m, d] = self.get_ymd() + let self._month = self.constructor.month_constructor.new(y, m) + return self._month +endfunction + +function! s:instance.year() dict abort + if has_key(self, '_year') | return self._year | endif + let self._year = self.constructor.year_constructor.new(self.get_year()) + return self._year +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/constructor/day_hybrid.vim b/bundle/calendar.vim/autoload/calendar/constructor/day_hybrid.vim new file mode 100644 index 000000000..63af399dc --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/constructor/day_hybrid.vim @@ -0,0 +1,73 @@ +" ============================================================================= +" Filename: autoload/calendar/constructor/day_hybrid.vim +" Author: itchyny +" License: MIT License +" Last Change: 2017/05/07 22:07:20. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +function! calendar#constructor#day_hybrid#new(y, m, d) abort + let constructor = extend({ 'switch_mjd': calendar#day#gregorian#new(a:y, a:m, a:d).mjd }, s:constructor) + let constructor.switch_day = calendar#day#gregorian#new_mjd(constructor.switch_mjd) + let constructor.month_constructor = calendar#constructor#month#new(constructor) + let constructor.year_constructor = calendar#constructor#year#new(constructor) + return constructor +endfunction + +let s:constructor = {} + +function! s:constructor.new(y, m, d) dict abort + let mjd = calendar#day#gregorian#new(a:y, a:m, a:d).mjd + if mjd < self.switch_mjd + let mjd = calendar#day#julian#new(a:y, a:m, a:d).mjd + if mjd > self.switch_mjd + let mjd = deepcopy(self.switch_mjd) + endif + endif + let instance = self.new_mjd(mjd) + let instance._ymd = [a:y, a:m, a:d] + return instance +endfunction + +function! s:constructor.new_mjd(mjd) dict abort + let instance = s:super_constructor.new_mjd(a:mjd) + let instance.constructor = self + let instance.switch_mjd = self.switch_mjd + let instance.switch_day = self.switch_day + return instance +endfunction + +function! s:constructor.today() dict abort + return self.new_mjd(calendar#day#today_mjd()) +endfunction + +let s:instance = {} + +function! s:instance.new(y, m, d) dict abort + return self.constructor.new(a:y, a:m, a:d) +endfunction + +function! s:instance.new_mjd(mjd) dict abort + return self.constructor.new_mjd(a:mjd) +endfunction + +function! s:instance.get_ymd() dict abort + if has_key(self, 'ymd') | return self.ymd | endif + let self.ymd = calendar#day#{self.get_calendar()}#new_mjd(self.mjd).get_ymd() + return self.ymd +endfunction + +function! s:instance.is_gregorian() dict abort + return self.mjd >= self.switch_mjd +endfunction + +function! s:instance.get_calendar() dict abort + return self.is_gregorian() ? 'gregorian' : 'julian' +endfunction + +let s:super_constructor = calendar#constructor#day#new(s:instance) + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/constructor/month.vim b/bundle/calendar.vim/autoload/calendar/constructor/month.vim new file mode 100644 index 000000000..bafe6b65a --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/constructor/month.vim @@ -0,0 +1,155 @@ +" ============================================================================= +" Filename: autoload/calendar/constructor/month.vim +" Author: itchyny +" License: MIT License +" Last Change: 2015/03/29 06:26:32. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +function! calendar#constructor#month#new(day_constructor) abort + return extend({ 'day_constructor': a:day_constructor, 'cache': {} }, s:constructor) +endfunction + +let s:constructor = {} + +function! s:constructor.new(y, m) dict abort + let instance = copy(s:instance) + let instance.day_constructor = self.day_constructor + let instance._ym = [a:y, a:m] + let instance.constructor = self + return instance +endfunction + +let s:instance = {} + +function! s:instance.new(y, m) dict abort + return self.constructor.new(a:y, a:m) +endfunction + +function! s:div(x, y) abort + return a:x/a:y-((a:x<0)&&(a:x%a:y)) +endfunction + +function! s:instance.add(diff) dict abort + let [y, m] = self.get_ym() + let m += a:diff - 1 + let y += s:div(m, 12) + let m -= 12 * s:div(m, 12) + let m += 1 + return self.new(y, m) +endfunction + +function! s:instance.sub(month) dict abort + let [ya, ma] = self.get_ym() + let [yb, mb] = a:month.get_ym() + return (ya - yb) * 12 + (ma - mb) +endfunction + +function! s:instance.eq(month) dict abort + return self.get_ym() == a:month.get_ym() +endfunction + +function! s:instance.eq_month(month) dict abort + return self.eq(a:month) +endfunction + +function! s:instance.eq_year(month) dict abort + return self.year().eq(a:month.year()) +endfunction + +function! s:instance.is_valid() dict abort + return self.head_day().is_valid() && self.last_day().is_valid() +endfunction + +function! s:instance.get_ym() dict abort + if has_key(self, 'ym') | return self.ym | endif + let self.ym = self.head_day().get_ymd()[:1] + return self.ym +endfunction + +function! s:instance.get_ym_string() dict abort + if has_key(self, 'ym_string') | return self.ym_string | endif + let ymd = self.head_day().get_ymd() + let self.ym_string = ymd[0] . '/' . ymd[1] + return self.ym_string +endfunction + +function! s:instance.get_year() dict abort + return self.get_ym()[0] +endfunction + +function! s:instance.get_month() dict abort + return self.get_ym()[1] +endfunction + +function! s:instance.get_day() dict abort + return self.head_day().get_day() +endfunction + +function! s:instance.head_day() dict abort + if has_key(self, '_head_day') | return self._head_day | endif + let self._head_day = self.day_constructor.new(self._ym[0], self._ym[1], 1) + if self._head_day.is_valid() + return self._head_day + else + let y = self._ym[0] + let m = self._ym[1] + let yy = self._ym[0] + let mm = self._ym[1] - 1 + if mm < 1 + let [yy, mm] = [yy - 1, mm + 12] + endif + let self._head_day = self.day_constructor.new(yy, mm, 1) + while self._head_day.get_year() < y || self._head_day.get_month() < m + let self._head_day = self._head_day.add(1) + endwhile + endif + return self._head_day +endfunction + +function! s:instance.last_day() dict abort + if has_key(self, '_last_day') | return self._last_day | endif + let [y, m] = [self._ym[0], self._ym[1]] + let m += 1 + if m > 12 | let [y, m] = [y + 1, m - 12] | endif + let self._last_day = self.new(y, m).head_day().add(-1) + return self._last_day +endfunction + +function! s:instance.days() dict abort + if has_key(self, '_days') | return self._days | endif + let self._days = self.last_day().sub(self.head_day()) + 1 + return self._days +endfunction + +function! s:instance.get_days() dict abort + if has_key(self, '__days') | return self.__days | endif + if has_key(self.constructor.cache, self.get_ym_string()) + return self.constructor.cache[self.get_ym_string()] + endif + let days = [] + call add(days, self.head_day()) + let l = self.last_day() + while !l.eq(days[-1]) + call add(days, days[-1].add(1)) + endwhile + let self.__days = days + let self.constructor.cache[self.get_ym_string()] = days + return days +endfunction + +function! s:instance.day() dict abort + return self.head_day() +endfunction + +function! s:instance.month() dict abort + if has_key(self, '_month') | return self._month | endif + let [y, m] = self.get_ym() + let self._month = self.new(y, m) + return self._month +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/constructor/view.vim b/bundle/calendar.vim/autoload/calendar/constructor/view.vim new file mode 100644 index 000000000..779a6ed24 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/constructor/view.vim @@ -0,0 +1,172 @@ +" ============================================================================= +" Filename: autoload/calendar/constructor/view.vim +" Author: itchyny +" License: MIT License +" Last Change: 2015/03/29 06:26:52. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +function! calendar#constructor#view#new(instance) abort + return extend({ 'instance': a:instance }, s:constructor) +endfunction + +let s:constructor = {} + +function! s:constructor.new(source) dict abort + let instance = extend(deepcopy(s:instance), deepcopy(self.instance)) + let instance.size = { 'x': 0, 'y': 0 } + let instance._size = instance.size + let instance.source = a:source + let instance._selected = 0 + return instance +endfunction + +let s:instance = {} + +function! s:instance.set_visible(value) dict abort + let self._visible = a:value +endfunction + +function! s:instance.is_visible() dict abort + sandbox return has_key(self, '_visible') ? self._visible : has_key(self.source, 'visible') ? eval(self.source.visible) : 1 +endfunction + +function! s:instance.on_top() dict abort + sandbox return has_key(self.source, 'on_top') ? eval(self.source.on_top) : 0 +endfunction + +function! s:instance.width() dict abort + return self.maxwidth() +endfunction + +function! s:instance.height() dict abort + return self.maxheight() +endfunction + +function! s:instance.sizex() dict abort + return self.size.x +endfunction + +function! s:instance.sizey() dict abort + return self.size.y +endfunction + +function! s:instance.set_size() dict abort + let self._size = copy(self.size) + let self.size.x = self.width() + let self.size.y = self.height() + if self._size != self.size && has_key(self, 'on_resize') + call self.on_resize() + endif + return self +endfunction + +function! s:instance.left() dict abort + sandbox return has_key(self.source, 'left') ? eval(self.source.left) : 0 +endfunction + +function! s:instance.top() dict abort + sandbox return has_key(self.source, 'top') ? eval(self.source.top) : 0 +endfunction + +function! s:instance.maxwidth() dict abort + sandbox return has_key(self.source, 'maxwidth') ? eval(self.source.maxwidth) : calendar#util#winwidth() - 1 +endfunction + +function! s:instance.maxheight() dict abort + sandbox return has_key(self.source, 'maxheight') ? eval(self.source.maxheight) : calendar#util#winheight() +endfunction + +function! s:instance.is_center() dict abort + return get(self.source, 'align', '') ==# 'center' +endfunction + +function! s:instance.is_vcenter() dict abort + return get(self.source, 'valign', '') ==# 'center' +endfunction + +function! s:instance.is_right() dict abort + return get(self.source, 'align', '') ==# 'right' +endfunction + +function! s:instance.is_bottom() dict abort + return get(self.source, 'valign', '') ==# 'bottom' +endfunction + +function! s:instance.is_absolute() dict abort + return get(self.source, 'position', '') ==# 'absolute' +endfunction + +function! s:instance.get_top() dict abort + return max([self.top() + (self.is_vcenter() ? (self.maxheight() - self.size.y) / 2 : self.is_bottom() ? (self.maxheight() - self.size.y) : 0), 0]) +endfunction + +function! s:instance.get_left() dict abort + return max([self.left() + (self.is_center() ? (self.maxwidth() - self.size.x + 1) / 2 : self.is_right() ? (self.maxwidth() - self.size.x) : 0), 0]) +endfunction + +function! s:instance.display_point() dict abort + return 1 +endfunction + +function! s:instance.gather(...) dict abort + let c = self.contents() + let l = self.get_left() + let p = self.get_top() + (a:0 ? a:1 : 0) + return map(c, 'v:val.move(l, p)') +endfunction + +function! s:instance.set_selected(selected) dict abort + let self._selected = a:selected + return self +endfunction + +function! s:instance.is_selected() dict abort + return self._selected +endfunction + +function! s:instance.set_index(index) dict abort + let self._index = a:index +endfunction + +function! s:instance.get_index() dict abort + return self._index +endfunction + +function! s:instance.updated() dict abort + return 1 +endfunction + +function! s:instance.timerange() dict abort + return '' +endfunction + +function! s:instance.action(action) dict abort + return 0 +endfunction + +function! s:instance.oneday(day, events) dict abort + let width = self.view.inner_width + let right = has_key(a:events, 'daynum') ? a:events.daynum : '' + if has_key(a:events, 'weeknum') && width > len(right) + 6 + let right = a:events.weeknum . (len(right) ? ' ' : '') . right + endif + if has_key(a:events, 'moon') && width > len(right) + 5 + let right = a:events.moon . right + endif + if width > len(right) + 3 && len(right) + let le = calendar#string#strdisplaywidth(right) + 1 + let right = ' ' . right + else + let le = 0 + let right = '' + endif + let day = (a:day < 10 ? ' ' : '') . a:day + let holiday = get(a:events, 'holiday', '') + return calendar#string#truncate(day . ' ' . holiday, width - le) . right +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/constructor/view_clock.vim b/bundle/calendar.vim/autoload/calendar/constructor/view_clock.vim new file mode 100644 index 000000000..959c700f2 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/constructor/view_clock.vim @@ -0,0 +1,221 @@ +" ============================================================================= +" Filename: autoload/calendar/constructor/view_clock.vim +" Author: itchyny +" License: MIT License +" Last Change: 2015/03/29 06:26:59. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +function! calendar#constructor#view_clock#new(instance) abort + return extend({ 'instance': a:instance }, s:constructor) +endfunction + +let s:constructor = {} + +function! s:constructor.new(source) dict abort + return extend(extend(s:super_constructor.new(a:source), s:instance), self.instance) +endfunction + +let s:instance = {} +let s:instance.letters = [] +let s:instance.prevscale = 0 +let s:instance.syntax = [] +let s:instance.diffs = [] +let s:instance.smaller = 0 +let s:instance.offsetx_start = 0 +let s:instance.colnum = 1 +let s:instance.winwidth = 0 +let s:instance.winheight = 0 +let s:instance.str = '' +let s:instance.len = 0 +let s:instance._colnum = 0 + +function! s:instance.get_scale(...) dict abort + let colnum = a:0 ? a:1 : self.colnum + let [h, w] = [self.maxheight(), self.maxwidth()] + if self.winwidth == w && self.winheight == h && self._colnum == colnum + return self.scale + endif + let str = self.max_letter()[0] + let len = calendar#pixel#len(str) + 2 * (len(str) - 1) + let scale = 0 + while w >= len * (scale + 1) * (15 + scale) / 15 + 1 && + \ h >= 6 * (scale + 1) * self.y_height * colnum + 1 + let scale += 1 + endwhile + if scale > 1 && self.smaller + let scale -= 1 + endif + let self.scale = scale + let self.winwidth = w + let self.winheight = h + let self._colnum = colnum + return scale +endfunction + +function! s:instance.width() dict abort + let str = self.get_letter()[0] + if self.str !=# str + let self.len = calendar#pixel#len(str) + 2 * (len(str) - 1) + endif + let [h, w] = [self.maxheight(), self.maxwidth()] + if self.winwidth != w || self.winheight != h + let scale = self.get_scale() + endif + let self.winwidth = w + let self.winheight = h + let self.str = str + return self.scale ? self.len * self.scale : len(str) +endfunction + +function! s:instance.height() dict abort + if self.winwidth != self.maxwidth() || self.winheight != self.maxheight() + let scale = self.get_scale() + endif + let self.one_height = self.scale ? 5 * self.scale : 1 + return self.scale ? self.one_height * self.y_height : 1 +endfunction + +function! s:instance.gen_syn(chr, offsetx, offsety, syn) dict abort + if !len(a:chr) + return [[], 0] + endif + if !self.scale + return [[calendar#text#new(a:chr, a:offsetx, a:offsety, '')], 1] + endif + let pixel = calendar#pixel#get(a:chr) + if type(pixel) != type([]) + return [[], 0] + endif + let syn = [] + let max = 0 + let j = 0 + let scale = self.scale + let pp = '' + let above_num = 0 + for p in pixel + if pp ==# p && above_num && len(syn) + let h = syn[-1].syn[0][4] + for i in range(above_num) + call syn[- 1 - i].height((h ? h : scale) + scale) + endfor + else + let max = max([max, (len(p) + 2) * scale]) + let i = 0 + let num = 0 + while i < len(p) + let i += len(matchstr(p, '^\.*', i)) + let matchlen = len(matchstr(p, '^[^.]*', i)) + if matchlen + if num + call add(syn[-1].syn, [a:syn, a:offsety + j * scale, a:offsetx + i * scale, a:offsetx + i * scale + matchlen * scale, scale]) + else + call add(syn, calendar#text#new(matchlen * scale, a:offsetx + i * scale, a:offsety + j * scale, a:syn).height(scale)) + let num += 1 + endif + endif + let i += matchlen + endwhile + let pp = p + let above_num = num + endif + let j += 1 + endfor + return [syn, max] +endfunction + +function! s:instance.set_contents() dict abort + let cs = self.get_letter() + let syntax = [] + let diffs = [] + let syn = 'NormalSpace' + let offsetx_start = 0 + for j in range(len(cs)) + if j >= self.y_height + break + endif + if self.prevscale == self.scale && len(self.letters) == len(cs) && self.letters[j] ==# cs[j] + let syntax_oneline = self.syntax[j] + let diffsj = self.diffs[j] + else + let syntax_oneline = [] + let diffsj = [] + let offsetx = len(cs[j]) ? - calendar#pixel#whitelen(cs[j][0]) * self.scale : 0 + let offsetx_start = offsetx + let offsety = j * (5 + self.scale + 1) + let css = split(cs[j], '\zs') + for i in range(len(css)) + if self.prevscale == self.scale && len(self.letters) == len(cs) && len(self.letters[j]) == len(css) && + \ self.letters[j][i] ==# css[i] && diffsj == (i ? self.diffs[j][:i - 1] : []) && offsetx_start == self.offsetx_start + call add(syntax_oneline, self.syntax[j][i]) + let diffx = self.diffs[j][i] + else + let [syns, diffx] = self.gen_syn(css[i], offsetx, offsety, syn) + call add(syntax_oneline, syns) + endif + let offsetx += diffx + call add(diffsj, diffx) + endfor + endif + call add(syntax, syntax_oneline) + call add(diffs, diffsj) + endfor + let self.letters = cs + let self.syntax = syntax + let self.prevscale = self.scale + let self.diffs = diffs + let self.offsetx_start = offsetx_start + let self.syn = [] + let ydict = {} + let j = 0 + for ss in syntax + for sss in ss + if self.scale + for ssss in sss + if has_key(ydict, ssss.y) + call extend(self.syn[ydict[ssss.y]].syn, ssss.syn) + else + call add(self.syn, deepcopy(ssss)) + let ydict[ssss.y] = j + let j += 1 + endif + endfor + else + call extend(self.syn, sss) + endif + endfor + endfor +endfunction + +function! s:instance.on_resize() dict abort + let self.letters = [] + let self.syntax = [] +endfunction + +function! s:instance.contents() dict abort + if self.letters != self.get_letter() + call self.set_contents() + endif + let syn = deepcopy(self.syn) + if self.is_selected() && len(self.syntax) && len(self.syntax[-1]) && len(self.syntax[-1][-1]) + let cur = deepcopy(self.syntax[-1][-1][-1]) + if len(cur.syn) && len(cur.syn[0]) > 3 + let cur.syn[0][0] = 'Cursor' + let cur.t = 1 + call cur.move(cur.syn[0][3] - cur.syn[0][2] - !!self.scale, cur.syn[0][4] ? cur.syn[0][4] - 1 : 0) + call add(syn, cur) + endif + endif + return syn +endfunction + +function! s:instance.updated() dict abort + return self.letters != self.get_letter() +endfunction + +let s:super_constructor = calendar#constructor#view#new(s:instance) + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/constructor/view_days.vim b/bundle/calendar.vim/autoload/calendar/constructor/view_days.vim new file mode 100644 index 000000000..e24f5a4ed --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/constructor/view_days.vim @@ -0,0 +1,778 @@ +" ============================================================================= +" Filename: autoload/calendar/constructor/view_days.vim +" Author: itchyny +" License: MIT License +" Last Change: 2017/05/07 23:06:06. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +function! calendar#constructor#view_days#new(instance) abort + return extend({ 'instance': a:instance }, s:constructor) +endfunction + +let s:constructor = {} + +function! s:constructor.new(source) dict abort + return extend(extend(s:super_constructor.new(a:source), s:instance), self.instance) +endfunction + +let s:instance = {} + +function! s:instance.height() dict abort + return max([self.maxheight(), 6]) +endfunction + +function! s:instance.on_resize() dict abort + let self.frame = copy(calendar#setting#frame()) + let width = calendar#string#strdisplaywidth(self.frame.vertical) + let self.view = {} + let self.view.width = (self.sizex() - width) / self.daynum / width * width + let h = max([(self.sizey() - 3) / 6, 1]) + let self.view.week_count = 5 + let self.view.dayheight = h < 3 ? h : max([(self.sizey() - 3) / max([self.view.week_count, 5]), 1]) + let self.view.hourheight = max([(self.sizey() - self.view.dayheight) / 24, 3]) + let self.view.blockmin = 60 / (self.view.hourheight - 1) + if !(self.view.width > 3 && self.view.dayheight > 1) + let self.frame = calendar#setting#get('frame_space') + let width = 1 + let self.view.width = (self.sizex() - width) / self.daynum + endif + let self.frame.width = calendar#string#strdisplaywidth(self.frame.vertical) + let self.frame.strlen = len(self.frame.vertical) + let self.element = {} + let self.element.splitter = repeat(self.frame.horizontal, (self.view.width - width) / width) + let self.element.white = repeat(' ', (self.view.width - width) / width * width) + let self.element.vwhite = self.frame.vertical . self.element.white + let self.element.format = '%2d' . repeat(' ', (self.view.width - width) / width * width - 2) + let self.view.realwidth = self.view.width - width + self.frame.strlen + let self.view.inner_width = self.view.width - width + let self.view.offset = self.view.dayheight > 1 ? 3 : 1 + let self.view.locale = calendar#setting#get('locale') + call self.set_day_name() + let self._cache_key = [] +endfunction + +function! s:instance.width() dict abort + let frame = calendar#setting#frame() + let width = calendar#string#strdisplaywidth(frame.vertical) + let w = max([(self.maxwidth() - calendar#setting#get('clock_12hour') * 7) / 8, 3]) + let hh = self.height() + let h = max([(hh - 3) / 6, 1]) + let h = h < 3 ? h : max([(hh - 3) / calendar#week#week_count(b:calendar.month()), 1]) + if !(w > 3 && h > 1) + let width = 1 + endif + let daynum = self.daynum + if daynum == 1 + let views = calendar#setting#get('views') + let i = index(views, 'day_1') + if i >= 0 + let days = filter([i > 0 ? views[i - 1] : '', i + 1 < len(views) ? views[i + 1] : ''], 'v:val =~# ''^day_\d$''') + if len(days) + let num = substitute(days[0], 'day_', '', '') + 0 + if 1 < num && num <= 7 + let daynum = num + endif + endif + endif + endif + return w * 7 / daynum / width * width * daynum + width +endfunction + +function! s:instance.get_min_day() dict abort + let day = b:calendar.day() + if has_key(self, 'min_day') + if day.sub(self.min_day) < 0 + let self.min_day = day + elseif day.sub(self.max_day) > 0 + let self.min_day = day.add(-self.daynum + 1) + endif + else + let self.min_day = day + endif + let self.max_day = self.min_day.add(self.daynum - 1) + return self.min_day +endfunction + +function! s:instance.cache_key() dict abort + if has_key(self, 'min_hour') && (self.min_hour < 0 || self.max_hour > 23) + return [] + else + return copy(self.min_max_hour()) + self.get_min_day().get_ymd() + [b:calendar.day().get_month()] + \ + calendar#day#today().get_ymd() + [calendar#setting#get('frame'), calendar#setting#get('first_day')] + \ + b:calendar.event.updated() + [get(g:, 'calendar_google_event_download')] + endif +endfunction + +function! s:instance.min_max_hour() dict abort + let height = self.height() - self.view.offset - self.view.dayheight + let heighthour = height / self.view.hourheight + let time = b:calendar.time() + let hour = time.hour() + if has_key(self, 'min_hour') + if hour < self.min_hour + let min = hour + elseif hour > self.max_hour + let min = self.min_hour + hour - self.max_hour + else + let min = self.min_hour + endif + else + let min = time.hour() - heighthour / 2 + 2 + endif + let min = max([min, 0]) + let max = min([min + heighthour - 1, 23]) + let min = max([max - heighthour + 1, 0]) + let max = min([min + heighthour - 1, 23]) + return [min, max] +endfunction + +function! s:instance.set_min_max_hour(hours) dict abort + let [self.min_hour, self.max_hour] = a:hours +endfunction + +function! s:instance.get_min_max_hour() dict abort + return [self.min_hour, self.max_hour] +endfunction + +function! s:instance.set_day_name() dict abort + let [h, w, ww] = [self.view.dayheight, self.view.width, self.view.realwidth] + let key = h . ',' . w . ',' . ww . ',' . calendar#setting#get('frame') . ',' + \ . calendar#setting#get('locale') . ',' . calendar#week#week_index(self.get_min_day()) . ',' . calendar#setting#get('first_day') + if !has_key(self, 'day_name_cache') + let self.day_name_cache = {} + endif + if has_key(self.day_name_cache, key) + let [self.day_name_text, self.day_name_syntax] = self.day_name_cache[key] + return + endif + let day_name = copy(calendar#message#get('day_name_long')) + let maxlen = max(map(copy(day_name), 'calendar#string#strdisplaywidth(v:val)')) + if maxlen >= self.view.inner_width + let day_name = copy(calendar#message#get('day_name')) + endif + let s = repeat([''], 3) + let syntax = [] + let x = self.frame.strlen + let idx = self.get_min_day().week() + for i in range(idx, idx + self.daynum - 1) + if h > 1 + let s[0] .= (i > idx ? self.frame.top : self.frame.topleft) . self.element.splitter + let s[2] .= (i > idx ? self.frame.junction : self.frame.left) . self.element.splitter + endif + let name = day_name[i % 7] + let wid = calendar#string#strdisplaywidth(name) + if wid >= self.view.inner_width + let name = calendar#string#truncate(name, max([2, self.view.inner_width])) + let wid = calendar#string#strdisplaywidth(name) + endif + let len = calendar#string#strdisplaywidth(self.element.splitter) + let whiteleft = repeat(' ', (len - wid) / 2) + let whiteright = repeat(' ', len - len(whiteleft) - wid) + let weekstr = whiteleft . name . whiteright + let s[h > 1] .= self.frame.vertical . weekstr + let syn = i % 7 == 0 ? 'SundayTitle' : i % 7 == 6 ? 'SaturdayTitle' : 'DayTitle' + if len(syntax) + call add(syntax[-1].syn, [syn, h > 1, x, x + len(weekstr), 0]) + else + call add(syntax, calendar#text#new(len(weekstr), x, h > 1, syn)) + endif + let x += len(weekstr) + self.frame.strlen + endfor + if h > 1 + let s[0] .= self.frame.topright + let s[1] .= self.frame.vertical + let s[2] .= self.frame.right + endif + let self.day_name_text = s + let self.day_name_syntax = syntax + let self.day_name_cache[key] = [s, syntax] +endfunction + +function! s:get_timeevts(events, blockmin) abort + let time_events = {} + let r = range(len(a:events)) + for i in r + if get(a:events[i], 'isTimeEvent') && has_key(a:events[i], 'hms') && has_key(a:events[i], 'endhms') + if a:events[i].ymd == a:events[i].endymd || + \ (a:events[i].endhms == [0, 0, 0] && + \ calendar#day#new(a:events[i].endymd[0], a:events[i].endymd[1], a:events[i].endymd[2]).sub( + \ calendar#day#new(a:events[i].ymd[0], a:events[i].ymd[1], a:events[i].ymd[2]) + \ ) == 1 + \ ) + let hour = a:events[i].hms[0] + let min = a:events[i].hms[1] / a:blockmin * a:blockmin + let endhour = a:events[i].ymd == a:events[i].endymd ? a:events[i].endhms[0] : 24 + let endmin = a:events[i].endhms[1] + let flg = 0 + let prev = [] + while (hour < endhour || hour == endhour && min < endmin) && hour <= 24 + let timestr = hour . ':' . min + if !has_key(time_events, timestr) + let time_events[timestr] = [] + endif + call add(time_events[timestr], [i, flg, get(a:events[i], 'syntax', '')]) + let prev = time_events[timestr][-1] + let flg = 1 + let min += a:blockmin + if min >= 60 + let min = 0 + let hour += 1 + endif + endwhile + if len(prev) > 1 && prev[1] + let prev[1] = 2 + endif + if len(prev) && prev[1] == 0 + let prev[1] = 4 + endif + endif + endif + endfor + let maxnum = 0 + let prevdict = {} + let hour = 0 + let min = 0 + let prevret = {} + let ret = {} + while hour <= 24 + let timestr = hour . ':' . min + if has_key(time_events, timestr) + let maxnum = max([maxnum, len(time_events[timestr])]) + let new = {} + let minind = 0 + let rr = range(len(time_events[timestr])) + for i in rr + let tvs = time_events[timestr][i] + if has_key(prevdict, tvs[0]) + let new[prevdict[tvs[0]]] = deepcopy(tvs) + endif + endfor + for i in rr + let tvs = time_events[timestr][i] + if !has_key(prevdict, tvs[0]) + while has_key(new, minind) + let minind += 1 + endwhile + let new[minind] = deepcopy(tvs) + let prevdict[tvs[0]] = minind + endif + endfor + let minind = 0 + let prevret[timestr] = [] + for i in range(maxnum) + if has_key(new, i) + call add(prevret[timestr], new[i]) + else + call add(prevret[timestr], [-1, 3, '']) + endif + endfor + else + let prevdict = {} + for [key, events] in items(prevret) + for event in events + call add(event, maxnum) + endfor + let ret[key] = events + endfor + let prevret = {} + let maxnum = 0 + endif + let min += a:blockmin + if min >= 60 + let min = 0 + let hour += 1 + endif + endwhile + return ret +endfunction + +function! s:instance.set_contents() dict abort + if self.frame.type !=# calendar#setting#get('frame') | call self.on_resize() | endif + call self.set_day_name() + let [f, v, e] = [self.frame, self.view, self.element] + let [h, w, ww] = [v.dayheight, v.width, v.realwidth] + let height = self.height() - v.offset - h + let bottompad = (self.height() - v.offset - h) % v.hourheight + 1 + let self.has_today = 0 + let hh = 1 <= h - 2 ? range(1, h - 2) : [] + let s = repeat([''], self.sizey()) + let today = calendar#day#today() + let month = b:calendar.month() + let day = b:calendar.day() + let syntax = deepcopy(self.day_name_syntax) + for i in range(len(self.day_name_text)) + let s[i] = self.day_name_text[i] + endfor + let [so, st, su, sa, tsu, tsa] = ['OtherMonth', 'Today', 'Sunday', 'Saturday', 'TodaySunday', 'TodaySaturday'] + let [i, j] = [0, 0] + let days = month.get_days() + let prev_days = month.add(-1).get_days() + let next_days = month.add(1).get_days() + let wn = calendar#week#week_index(days[0]) + let sub = day.sub(wn ? prev_days[-wn] : days[0]) + let wnum = sub / 7 + let ld = wn + len(days) + let events = b:calendar.event.get_events(day.get_year(), day.get_month()) + let head = self.get_min_day().sub(wn ? prev_days[-wn] : days[0]) + let range = range(head, head + self.daynum - 1) + let [self.min_hour, self.max_hour] = self.min_max_hour() + let longevt = [] + let longtimeevt = [] + let self.timeevent_syntax = [] + let event_start_time = calendar#setting#get('event_start_time') + let event_start_time_minwidth = calendar#setting#get('event_start_time_minwidth') + let clock_12hour = calendar#setting#get('clock_12hour') + for p in range + let d = p < wn ? prev_days[-wn + p] : p < ld ? days[p - wn] : next_days[p - ld] + let evts = get(events, join(d.get_ymd(), '-'), { 'events': [] } ) + let y = v.offset + h * j + let s[y] .= f.vertical + let s[y] .= self.oneday(d.get_day(), evts) + let is_today = today.eq(d) + if is_today + let self.has_today = 1 + endif + let syn = is_today ? st : d.is_sunday() || get(evts, 'hasHoliday') ? su : d.is_saturday() ? sa : '' + if syn !=# '' + let l = is_today ? len(calendar#string#truncate_reverse(s[y], v.inner_width)) : 2 + let syn2 = !is_today ? '' : d.is_sunday() || get(evts, 'hasHoliday') ? tsu : d.is_saturday() ? tsa : '' + let x = len(calendar#string#truncate(s[y], w * i + f.width)) + if syn2 !=# '' + let x += 2 + let l -= 2 + endif + call add(syntax, calendar#text#new(l, x, y, syn)) + if syn2 !=# '' + let l = 2 + let x = len(calendar#string#truncate(s[y], w * i + f.width)) + if len(syntax) && syntax[-1].y == y + call add(syntax[-1].syn, [syn2, y, x, x + l, 0]) + else + call add(syntax, calendar#text#new(l, x, y, syn2)) + endif + endif + endif + let z = 0 + let longevtIndex = 0 + for x in hh + if longevtIndex < len(longevt) && longevt[longevtIndex].viewoffset == x + let lastday = d.get_day() == longevt[longevtIndex].endymd[2] || + \ (get(longevt[longevtIndex], 'isTimeEvent') && + \ longevt[longevtIndex].endhms == [0, 0, 0] && + \ calendar#day#new(longevt[longevtIndex].endymd[0], longevt[longevtIndex].endymd[1], longevt[longevtIndex].endymd[2]).sub(d) == 1 + \ ) + let eventtext = repeat('=', v.inner_width - lastday) . (lastday ? ']' : '') + let splitter = i ? repeat('=', f.width) : f.vertical + let s[y + x] .= splitter . eventtext + if has_key(longevt[longevtIndex], 'syntax') + let l = len(eventtext) + let syn = longevt[longevtIndex].syntax + let yy = y + x + let xx = len(s[y + x]) - l - (i ? f.width : 0) + let l = l + (i ? f.width : 0) + call add(syntax, calendar#text#new(l, xx, yy, syn)) + endif + let longevtIndex += 1 + else + while z < len(evts.events) && (!has_key(evts.events[z], 'summary') || evts.events[z].isHoliday || evts.events[z].isMoon || evts.events[z].isDayNum || evts.events[z].isWeekNum) + let z += 1 + endwhile + if z < len(evts.events) + let is_long_event = evts.events[z].ymd != evts.events[z].endymd && + \ (!get(evts.events[z], 'isTimeEvent') || + \ evts.events[z].endhms != [0, 0, 0] || + \ calendar#day#new(evts.events[z].endymd[0], evts.events[z].endymd[1], evts.events[z].endymd[2]).sub( + \ calendar#day#new(evts.events[z].ymd[0], evts.events[z].ymd[1], evts.events[z].ymd[2]) + \ ) > 1 + \ ) + if is_long_event + let trailing = ' ' . repeat('=', v.inner_width) + call add(longevt, extend(evts.events[z], { 'viewoffset': x })) + else + let trailing = '' + endif + let starttime = event_start_time && self.view.width >= event_start_time_minwidth + \ && get(evts.events[z], 'isTimeEvent') ? evts.events[z].starttime . ' ' : '' + let eventtext = calendar#string#truncate(starttime . evts.events[z].summary . trailing, v.inner_width) + if has_key(evts.events[z], 'syntax') + let l = len(eventtext) + let xx = len(s[y + x]) + len(f.vertical) + let yy = y + x + call add(syntax, calendar#text#new(l, xx, yy, evts.events[z].syntax)) + endif + let s[y + x] .= f.vertical . eventtext + let z += 1 + else + let s[y + x] .= e.vwhite + endif + endif + endfor + call sort(filter(longevt, 'calendar#view#month#longevt_filter(v:val, d)'), 'calendar#view#month#sorter') + let time_events = s:get_timeevts(evts.events, v.blockmin) + for k in range(height) + if k < height - bottompad + if (k + 1) % v.hourheight + let hour = self.min_hour + k / v.hourheight + let min = (k % v.hourheight) * v.blockmin + let timestr = hour . ':' . min + if has_key(time_events, timestr) && len(time_events[timestr]) + let maxnum = get(time_events[timestr][0], 3, 1) + let tevts = map(deepcopy(time_events[timestr]), 'v:val[0] >= 0 ? evts.events[v:val[0]] : {}') + let onelen = max([(v.inner_width + 2) / maxnum - f.width, f.width * 3]) + let hourcontents = '' + let texts = [] + let syns = [] + let totallen = 0 + let yy = v.offset + h + k + let ya = yy - 1 + let framelen = v.inner_width / f.width * f.strlen + let xx = len(s[ya]) - framelen + for ii in range(len(tevts)) + let l = maxnum > 1 ? (max([0, min([onelen, v.inner_width - totallen])]) - 1) / f.width * f.width : v.inner_width + if l >= f.width * 2 + let flg = time_events[timestr][ii][1] + let border = flg == 3 ? [repeat(' ', f.width), repeat(' ', f.width)] : flg == 1 ? repeat([f.vertical], 2) : [f.bottomleft, f.bottomright] + let rep = flg == 3 || flg == 1 ? repeat(' ', f.width) : f.horizontal + if flg && flg < 4 + call add(texts, border[0] . repeat(rep, l / f.width - 2) . border[1]) + if flg < 3 + if (k % v.hourheight) == 0 && k + let cutlen = len(s[ya][(xx):]) + let leftpart = s[ya][:len(s[ya]) - cutlen - 1] + let rightpart = s[ya][len(s[ya]) - cutlen + l / f.width * f.strlen :] + let s[ya] = leftpart . f.vertical . repeat(' ', l - f.width * 2) . f.vertical . rightpart + call add(syntax, calendar#text#new(l - f.width * 2 + f.strlen * 2, xx, ya, get(tevts[ii], 'syntax', ''))) + let xx += l - 2 * f.width + 2 * f.strlen + f.strlen + endif + else + let xx += l / f.width * f.strlen + f.strlen + endif + else + let eventsummary = get(tevts[ii], 'summary', '') + let smallspace = repeat(' ', f.width - 1 - (calendar#string#strdisplaywidth(eventsummary) + f.width - 1) % f.width) + let newtext = calendar#string#truncate(eventsummary . smallspace . repeat(f.horizontal, l), l - f.width) . (flg ? f.horizontal : f.topright) + call add(texts, newtext) + let xx += l / f.width * f.strlen + f.strlen + endif + call add(syns, get(tevts[ii], 'syntax', '')) + let totallen += onelen + else + let xx += l / f.width * f.strlen + f.strlen + endif + endfor + let xx = len(s[yy]) + f.strlen + let hourcontents = calendar#string#truncate(join(texts, repeat(' ', f.width)), v.inner_width) + for ii in range(len(texts)) + let l = len(texts[ii]) + if len(syns[ii]) + call extend(time_events[timestr][ii], [l, xx, yy, syns[ii]]) + call add(syntax, calendar#text#new(l, xx, yy, syns[ii])) + endif + let xx += l + f.width + endfor + else + let hourcontents = e.white + endif + let s[v.offset + h + k] .= repeat(f.vertical . hourcontents, 1) + else + let s[v.offset + h + k] .= repeat(f.vertical . e.splitter, 1) + endif + endif + endfor + call add(self.timeevent_syntax, deepcopy(time_events)) + if h > 1 + let frame = i ? (j + 1 == 7 ? f.bottom : f.junction) : j + 1 == 7 ? f.bottomleft : f.left + let s[y + h - 1] .= frame . e.splitter + endif + if i == 6 + let [i, j] = [0, j + 1] + else + let i = i + 1 + endif + endfor + for i in range(1) + for j in range(h - 1) + let s[v.offset + h * i + j] .= f.vertical + endfor + let s[v.offset + h * i + h - 1] .= (i + 1 == 7 ? f.bottomright : f.right) + endfor + let s[self.height() - bottompad] .= f.bottomleft . repeat(e.splitter . f.bottom, self.daynum - 1) . e.splitter . f.bottomright + for j in range(height) + if j < height - bottompad + let s[v.offset + h + j] .= f.vertical + endif + if !((j + 1) % v.hourheight) + let hour = self.min_hour + j / v.hourheight + 1 + if clock_12hour + let postfix = hour < 12 || hour == 24 ? ' a.m.' : ' p.m.' + let hour = calendar#time#hour12(hour) + else + let postfix = '' + endif + let s[v.offset + h + j] .= printf('%2d:%02d', hour, 0) . postfix + endif + if !j + let hour = self.min_hour + if clock_12hour + let postfix = ' a.m.' + let hour = calendar#time#hour12(hour) + else + let postfix = '' + endif + let s[v.offset + h - 1] .= printf('%2d:%02d', hour, 0) . postfix + endif + endfor + let self._cache_key = self.cache_key() + let self.days = map(range(len(s)), 'calendar#text#new(s[v:val], 0, v:val, "")') + let self.syntax = syntax + let self.min_day = self.get_min_day() +endfunction + +function! s:instance.contents() dict abort + if self._cache_key != self.cache_key() | call self.set_contents() | endif + let [f, v, e] = [self.frame, self.view, self.element] + let select = [] + let select_over = [] + let cursor = [] + let now = calendar#time#now() + if self.is_selected() + for [i, hour] in self.select_index() + for h in range(v.hourheight - 1) + let y = v.offset + v.dayheight + v.hourheight * (hour - self.min_hour) + h + let x = len(calendar#string#truncate(self.days[y].s, v.width * i + f.width)) + let z = len(calendar#string#truncate(self.days[y].s, v.width * (i + 1))) + let timestr = hour . ':' . (v.blockmin * h) + if has_key(self.timeevent_syntax[i], timestr) + for time_event in self.timeevent_syntax[i][timestr] + if len(time_event) == 8 + call add(select_over, calendar#text#new(time_event[4], time_event[5], time_event[6], time_event[7] . 'Select')) + endif + endfor + endif + call add(select, calendar#text#new(z - x, x, y, 'Select')) + endfor + endfor + let y = v.offset + v.dayheight + v.hourheight * (hour - self.min_hour) + let x = len(calendar#string#truncate(self.days[y].s, v.width * i + f.width)) + let cursor = [calendar#text#new(0, x, y, 'Cursor')] + endif + if self.has_today + let i = calendar#day#today().sub(self.get_min_day()) + let h = now.minute()/ (60 / (self.view.hourheight - 1)) + if self.min_hour <= now.hour() && now.hour() <= self.max_hour + let y = v.offset + v.dayheight + v.hourheight * (now.hour() - self.min_hour) + h + let x = len(calendar#string#truncate(self.days[y].s, v.width * i + f.width)) + let z = len(calendar#string#truncate(self.days[y].s, v.width * (i + 1))) + let nowsyn = [calendar#text#new(z - x, x, y, 'Today')] + else + let nowsyn = [] + endif + else + let nowsyn = [] + endif + return deepcopy(self.days) + select + deepcopy(self.syntax) + select_over + cursor + nowsyn +endfunction + +function! s:instance.select_index() dict abort + let lasti = b:calendar.day().sub(self.get_min_day()) + let lasthour = b:calendar.time().hour() + if !b:calendar.visual_mode() + return [[lasti, lasthour]] + endif + let last = lasti * 24 + lasthour + let starti = b:calendar.visual_start_day().sub(self.get_min_day()) + let starthour = b:calendar.visual_start_time().hour() + let start = starti * 24 + starthour + let ret = [] + if b:calendar.is_visual() + for i in range(min([start, last]), max([start, last])) + let j = s:div(i, 24) + let k = i - j * 24 + if [j, k] != [lasti, lasthour] && 0 <= j && j < self.daynum && self.min_hour <= k && k <= self.max_hour + call add(ret, [j, k]) + endif + endfor + elseif b:calendar.is_line_visual() + for j in range(min([starti, lasti]), max([starti, lasti])) + for k in range(24) + if [j, k] != [lasti, lasthour] && 0 <= j && j < self.daynum && self.min_hour <= k && k <= self.max_hour + call add(ret, [j, k]) + endif + endfor + endfor + elseif b:calendar.is_block_visual() + for j in range(min([starti, lasti]), max([starti, lasti])) + for k in range(min([starthour, lasthour]), max([starthour, lasthour])) + if [j, k] != [lasti, lasthour] && 0 <= j && j < self.daynum && self.min_hour <= k && k <= self.max_hour + call add(ret, [j, k]) + endif + endfor + endfor + else + endif + call add(ret, [lasti, lasthour]) + return ret +endfunction + +function! s:div(x, y) abort + return a:x/a:y-((a:x<0)&&(a:x%a:y)) +endfunction + +function! s:instance.timerange() dict abort + let hour = b:calendar.time().hour() + if !b:calendar.visual_mode() + return printf('%d:00-%d:00 ', hour, hour + 1) + endif + let x = b:calendar.day() + let xh = b:calendar.time().hour() + let y = b:calendar.visual_start_day() + let yh = b:calendar.visual_start_time().hour() + let recurrence = '' + if b:calendar.is_line_visual() + if x.sub(y) >= 0 + if x.get_year() == y.get_year() + return printf('%d/%d-%d/%d ', y.get_month(), y.get_day(), x.get_month(), x.get_day()) . recurrence + else + return printf('%d/%d/%d-%d/%d/%d ', y.get_year(), y.get_month(), y.get_day(), x.get_year(), x.get_month(), x.get_day()) . recurrence + endif + else + if x.get_year() == y.get_year() + return printf('%d/%d-%d/%d ', x.get_month(), x.get_day(), y.get_month(), y.get_day()) . recurrence + else + return printf('%d/%d/%d-%d/%d/%d ', x.get_year(), x.get_month(), x.get_day(), y.get_year(), y.get_month(), y.get_day()) . recurrence + endif + endif + elseif b:calendar.is_block_visual() + if x.sub(y) >= 0 + let rec = x.sub(y) + 1 + let [yh, xh] = [min([xh, yh]), max([xh, yh])] + let x = y + else + let rec = y.sub(x) + 1 + let [xh, yh] = [min([xh, yh]), max([xh, yh])] + let y = x + endif + let recurrence = rec > 1 ? rec . 'days ' : '' + endif + if x.sub(y) == 0 && !len(recurrence) + return printf('%d:00 - %d:00 ', min([xh, yh]), max([xh, yh]) + 1) + elseif x.sub(y) >= 0 + if x.get_year() == y.get_year() + return printf('%d/%d %d:00 - %d/%d %d:00 ', y.get_month(), y.get_day(), yh, x.get_month(), x.get_day(), xh + 1) . recurrence + else + return printf('%d/%d/%d %d:00 - %d/%d/%d %d:00 ', y.get_year(), y.get_month(), y.get_day(), yh, x.get_year(), x.get_month(), x.get_day(), xh + 1) . recurrence + endif + else + if x.get_year() == y.get_year() + return printf('%d/%d %d:00 - %d/%d %d:00 ', x.get_month(), x.get_day(), xh, y.get_month(), y.get_day(), yh + 1) . recurrence + else + return printf('%d/%d/%d %d:00 - %d/%d/%d %d:00 ', x.get_year(), x.get_month(), x.get_day(), xh, y.get_year(), y.get_month(), y.get_day(), yh + 1) . recurrence + endif + endif +endfunction + +function! s:instance.action(action) dict abort + let d = b:calendar.day() + let hday = b:calendar.month().head_day() + let lday = b:calendar.month().last_day() + let hour = b:calendar.time().hour() + let wnum = d.sub(self.get_min_day()) + if a:action ==# 'left' + call b:calendar.move_day(get(self, 'stopend') ? max([-v:count1, -wnum]) : -v:count1) + elseif a:action ==# 'right' + call b:calendar.move_day(get(self, 'stopend') ? min([v:count1, -wnum + self.daynum - 1]) : v:count1) + elseif index(['prev', 'next', 'space', 'add', 'subtract'], a:action) >= 0 + call b:calendar.move_day(v:count1 * (index(['prev', 'subtract'], a:action) >= 0 ? -1 : 1)) + elseif index(['down', 'up'], a:action) >= 0 + call b:calendar.move_hour(v:count1 * (a:action ==# 'down' ? 1 : -1)) + elseif index(['plus', 'minus'], a:action) >= 0 + let h = v:count1 * (a:action ==# 'plus' ? 1 : -1) + while h > 23 - hour + let h = h - 24 + let wnum -= self.daynum + endwhile + while h < - hour + let h = h + 24 + let wnum += self.daynum + endwhile + call b:calendar.move_hour(h) + if has_key(self, 'min_day') && has_key(self, 'max_day') + if self.min_day.sub(d.add(-wnum)) > 0 || self.max_day.sub(d.add(-wnum)) < 0 + let self.min_day = self.min_day.add(s:div(-wnum + self.daynum - 1, self.daynum) * self.daynum) + let self.max_day = self.max_day.add(s:div(-wnum + self.daynum - 1, self.daynum) * self.daynum) + endif + endif + call b:calendar.move_day(-wnum) + elseif index(['down_big', 'up_big'], a:action) >= 0 + let diff = self.max_hour - self.min_hour + let dir = a:action ==# 'down_big' ? 1 : -1 + let di = max([min([v:count1 * dir * diff * 2 / 3, 23 - hour]), - hour]) + if dir > 0 + let self.min_hour = self.min_hour + v:count1 * dir * diff + let self.max_hour = self.min_hour + diff + else + let self.max_hour = self.max_hour + v:count1 * dir * diff + let self.min_hour = self.max_hour - diff + endif + call b:calendar.move_hour(di) + elseif index(['down_large', 'up_large'], a:action) >= 0 + let diff = self.max_hour - self.min_hour + let dir = a:action ==# 'down_large' ? 1 : -1 + let di = max([min([(dir > 0 ? self.max_hour : self.min_hour) - hour + (v:count1 - 1) * dir * diff, 23 - hour]), - hour]) + if dir > 0 + let self.min_hour = self.min_hour + v:count1 * dir * diff + let self.max_hour = self.min_hour + diff + else + let self.max_hour = self.max_hour + v:count1 * dir * diff + let self.min_hour = self.max_hour - diff + endif + call b:calendar.move_hour(di) + elseif a:action ==# 'line_head' + call b:calendar.move_day(-wnum) + elseif a:action ==# 'line_middle' + call b:calendar.move_day(-wnum + (self.daynum - 1) / 2) + elseif a:action ==# 'line_last' + call b:calendar.move_day(self.daynum - 1 - wnum) + elseif a:action ==# 'bar' + call b:calendar.move_day(-wnum + min([v:count1 - 1, self.daynum - 1])) + elseif a:action ==# 'first_line' || a:action ==# 'first_line_head' || (a:action ==# 'last_line' && v:count) + call b:calendar.move_hour((v:count ? min([v:count1, 23]) : 0) - hour) + elseif a:action ==# 'last_line' + call b:calendar.move_hour((v:count ? max([v:count1, 23]) : 23) - hour) + elseif a:action ==# 'last_line_last' + call b:calendar.move_hour((v:count ? max([v:count1, 23]) : 23) - hour) + elseif index(['scroll_down', 'scroll_up'], a:action) >= 0 + let diff = v:count1 * (a:action =~# 'down' ? 1 : -1) + let old_hours = [self.min_hour, self.max_hour] + let self.min_hour += diff + let self.max_hour += diff + let new_hours = self.min_max_hour() + if old_hours == new_hours + call b:calendar.move_hour(diff) + endif + elseif index(['scroll_top_head', 'scroll_top', 'scroll_bottom_head', 'scroll_bottom'], a:action) >= 0 + let self.min_hour += 23 * (a:action =~# 'top' ? 1 : -1) + let self.max_hour += 23 * (a:action =~# 'top' ? 1 : -1) + call b:calendar.move_day(a:action =~# 'head' ? -wnum : 0) + elseif index(['scroll_center_head', 'scroll_center'], a:action) >= 0 + let diff = self.max_hour - self.min_hour + let self.min_hour = hour - diff / 2 + 1 + let self.max_hour = self.min_hour + diff + call b:calendar.move_day(a:action =~# 'head' ? -wnum : 0) + elseif a:action ==# 'command_enter' && mode() ==# 'c' && getcmdtype() ==# ':' + let cmd = calendar#util#getcmdline() + if cmd =~# '^\s*\d\+\s*$' + let c = max([min([matchstr(cmd, '\d\+') * 1, 23]), 0]) + call b:calendar.move_hour(c - hour) + return calendar#util#update_keys() + endif + endif +endfunction + +let s:super_constructor = calendar#constructor#view#new(s:instance) + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/constructor/view_months.vim b/bundle/calendar.vim/autoload/calendar/constructor/view_months.vim new file mode 100644 index 000000000..75ab8121f --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/constructor/view_months.vim @@ -0,0 +1,348 @@ +" ============================================================================= +" Filename: autoload/calendar/constructor/view_months.vim +" Author: itchyny +" License: MIT License +" Last Change: 2017/05/07 23:07:32. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +function! calendar#constructor#view_months#new(instance) abort + return extend({ 'instance': a:instance }, s:constructor) +endfunction + +let s:constructor = {} + +function! s:constructor.new(source) dict abort + return extend(extend(s:super_constructor.new(a:source), s:instance), self.instance) +endfunction + +let s:instance = {} + +function! s:instance.is_full() dict abort + return self.x_months * self.y_months == 12 +endfunction + +function! s:instance.get_months() dict abort + if self.is_full() + return b:calendar.year().get_months() + else + let m = b:calendar.month() + let months = [m] + for i in range(self.x_months * self.y_months / 2) + call add(months, months[-1].add(1)) + endfor + for i in range((self.x_months * self.y_months - 1) / 2) + call insert(months, months[0].add(-1), 0) + endfor + return months + endif +endfunction + +function! s:instance.width() dict abort + let daywidth = 2 + let pad = 100 + while pad > daywidth * 7 + let daywidth += 1 + let pad = self.x_months > 1 ? max([(self.maxwidth() - daywidth * 7 * self.x_months)/2 / (self.x_months - 1), 2]) : 0 + endwhile + let self.pad = pad + let self.daywidth = daywidth + return (daywidth * 7 + pad) * self.x_months - pad - self.daywidth + 2 +endfunction + +function! s:instance.height() dict abort + return self.y_months > 1 ? max([9, (self.maxheight()) * 4/5 / self.y_months]) * self.y_months : 9 +endfunction + +function! s:instance.display_point() dict abort + let w = self.maxwidth() - 2 + let h = self.maxheight() + let lw = w - self.width() + let lh = (h - self.height()) * 2 + return (lw >= 0 && lh >= 0) * (lw + lh + (lw - lh >= 0 ? lw - lh : - (lw - lh)) * 5) +endfunction + +function! s:instance.on_resize() dict abort + let self.view = {} + let self.view.width = ((self.sizex() + self.pad + self.daywidth - 2)/ self.x_months - self.pad) / 7 + let self.view.pad = self.pad + let self.view.height = self.sizey() / self.y_months + let self.view.dheight = 1 + let self.view.dheight = max([1, self.view.height / 8]) + let self.view.offset = self.view.dheight * 2 + let self.element = {} + let self.element.pad = repeat(' ', self.view.pad) + let self.element.format = '%2d' . repeat(' ', self.view.width - 2) + let self.element.white = repeat(' ', self.view.width) + let self._today = [0, 0, 0] + let self._month = [0, 0] + let self._year = 0 + call self.set_day_name() +endfunction + +function! s:instance.set_day_name() dict abort + let day_name = copy(calendar#message#get('day_name')) + let [v, e] = [self.view, self.element] + let [mh, h, w] = [v.dheight, v.height, v.width] + let syntax = [] + let day_names = '' + let offsetx = [0] + let index = calendar#week#first_day_index() + for i in range(index, index + 6) + let name = day_name[i % 7] + let day_names .= calendar#string#truncate(name, 2) . repeat(' ', self.view.width - 2) + call add(offsetx, len(day_names)) + endfor + for j in range(self.y_months) + let y = h * j + v.offset / 2 + let f = 1 + let daytitles = [] + for i in range(self.x_months) + call add(daytitles, calendar#text#new(len(day_names) - (self.view.width - 2), (offsetx[-1] + v.pad) * i, y, 'DayTitle')) + for k in range(index, index + 6) + let l = k % 7 + let is_sunday = l == 0 + let is_saturday = l == 6 + if is_sunday || is_saturday + let x = (offsetx[-1] + v.pad) * i + offsetx[k - index] + let name = day_name[l] + let weekstr = calendar#string#truncate(name, 2) + let syn = is_sunday ? 'SundayTitle' : is_saturday ? 'SaturdayTitle' : '' + call daytitles[-1].over(calendar#text#new(len(weekstr), x, y, syn)) + endif + endfor + endfor + for i in range(len(daytitles)) + if i + call extend(syntax[-1].syn, daytitles[i].syn) + else + call add(syntax, daytitles[i]) + endif + endfor + endfor + let self.day_name_texts = syntax + let self.day_names = day_names + let self.day_names_len = offsetx[-1] + let self._first_day = calendar#setting#get('first_day') +endfunction + +function! s:instance.changed() dict abort + if self._today != calendar#day#today().get_ymd() || get(self, '_first_day', '') != calendar#setting#get('first_day') + return 1 + elseif self.is_full() + return self._year != b:calendar.year().get_y() + else + return self._month != b:calendar.month().get_ym() + endif +endfunction + +function! s:instance.set_contents() dict abort + let month_name = copy(calendar#message#get('month_name_long')) + let self.month_names_offset = [] + for i in range(self.y_months) + call add(self.month_names_offset, []) + endfor + let year = b:calendar.year() + let month = b:calendar.month() + let s = repeat([''], self.sizey()) + let syntax = deepcopy(self.day_name_texts) + let [v, e] = [self.view, self.element] + let [mh, h, w] = [v.dheight, v.height, v.width] + let [i, j] = [0, 0] + let today = calendar#day#today() + let self.sun_position = [] + let self.sat_position = [] + let self.top_syntax = [] + let months = self.get_months() + let week_number = calendar#setting#get('week_number') + for m in months + if len(s[h * j]) + for mj in range(h) + let s[mj + h * j] .= mj < v.offset ? e.pad : e.pad[2:] + endfor + endif + let [mi, mj] = [0, 0] + let monthname = month_name[m.get_month() - 1] + let monthnamelen = calendar#string#strdisplaywidth(monthname) + let holidays = b:calendar.event.get_holidays(m.get_year(), m.get_month()) + call add(self.month_names_offset[j], len(s[mh * mj + h * j])) + if monthnamelen >= w * 6 + 2 + let s[mh * mj + h * j] .= calendar#string#truncate(monthname, w * 7 - 1) . ' ' + else + let whiteleft = (w * 6 + 3 - monthnamelen) / 2 + let whiteright = w * 7 - monthnamelen - whiteleft + let s[mh * mj + h * j] .= repeat(' ', whiteleft) . monthname . repeat(' ', whiteright) + endif + call add(self.month_names_offset[j], len(s[mh * mj + h * j])) + let s[mh * mj + h * j + v.offset / 2] .= self.day_names + let days = m.get_days() + let prev_days = calendar#week#is_first_day(days[0]) ? [] : m.add(-1).get_days() + let next_days = calendar#week#is_last_day(days[-1]) ? [] : m.add(1).get_days() + let week_count = calendar#week#week_count(m) + let wn = calendar#week#week_index(days[0]) + let ld = wn + len(days) + let sun = [-1, -1, -1] + let sat = [-1, -1, -1] + for p in range(week_count * 7) + let d = p < wn ? prev_days[-wn + p] : p < ld ? days[p - wn] : next_days[p - ld] + let x = (w * 7 + v.pad) * i + v.width * mi + let y = mh * mj + h * j + v.offset + if wn <= p && p < ld + let s[y] .= printf(e.format, d.get_day()) + if today.eq(d) + for k in range(mh) " Do not use .height() + call add(self.top_syntax, calendar#text#new(2, x, y + k, 'Today')) + endfor + elseif has_key(holidays, join(d.get_ymd(), '-')) + for k in range(mh) " Do not use .height() + call add(self.top_syntax, calendar#text#new(2, x, y + k, 'Sunday')) + endfor + elseif d.is_sunday() + if sun[0] < 0 | let sun[0] = x | endif + let sun[2 - (sun[1] < 0)] = y + elseif d.is_saturday() + if sat[0] < 0 | let sat[0] = x | endif + let sat[2 - (sat[1] < 0)] = y + endif + let dd = d + else + let s[y] .= e.white + endif + if mi == 6 + let [mi, mj] = [0, mj + 1] + if week_number + call add(self.top_syntax, calendar#text#new(2, len(s[y]), y, 'Comment')) + let s[y] .= printf('%2d', calendar#week#week_number(dd)) + else + let s[y] .= ' ' + endif + else + let mi = mi + 1 + endif + endfor + if sun[0] >= 0 + if sun[2] < 0 | let sun[2] = sun[1] | endif + if len(syntax) && syntax[-1].y == sun[1] + call add(syntax[-1].syn, ['Sunday', sun[1], sun[0], sun[0] + 2, sun[2] - sun[1] + mh]) + elseif len(syntax) > 1 && syntax[-2].y == sun[1] + call add(syntax[-2].syn, ['Sunday', sun[1], sun[0], sun[0] + 2, sun[2] - sun[1] + mh]) + else + call add(syntax, calendar#text#new(2, sun[0], sun[1], 'Sunday').height(sun[2] - sun[1] + mh)) + endif + endif + if sat[0] >= 0 + if sat[2] < 0 | let sat[2] = sat[1] | endif + if len(syntax) && syntax[-1].y == sat[1] + call add(syntax[-1].syn, ['Saturday', sat[1], sat[0], sat[0] + 2, sat[2] - sat[1] + mh]) + elseif len(syntax) > 1 && syntax[-2].y == sat[1] + call add(syntax[-2].syn, ['Saturday', sat[1], sat[0], sat[0] + 2, sat[2] - sat[1] + mh]) + else + call add(syntax, calendar#text#new(2, sat[0], sat[1], 'Saturday').height(sat[2] - sat[1] + mh)) + endif + endif + call add(self.sun_position, sun) + call add(self.sat_position, sat) + for jj in range(mj, h - v.offset) + let y = mh * jj + h * j + v.offset + if y < len(s) && y < h * (j + 1) + let s[y] .= repeat(e.white, 7) . ' ' + else + break + endif + endfor + if i == self.x_months - 1 | let [i, j] = [0, j + 1] | else | let i = i + 1 | endif + if j >= self.y_months | break | endif + endfor + let self._today = today.get_ymd() + let self._first_day = calendar#setting#get('first_day') + if self.is_full() + let self._year = b:calendar.year().get_y() + else + let self._month = b:calendar.month().get_ym() + endif + let self.days = map(range(len(s)), 'calendar#text#new(s[v:val], 0, v:val, "")') + let self.syntax = syntax +endfunction + +function! s:instance.contents() dict abort + if get(self, '_first_day', '') != calendar#setting#get('first_day') | call self.on_resize() | endif + if self.changed() | call self.set_contents() | endif + let [v, e] = [self.view, self.element] + let [mh, h, w] = [v.dheight, v.height, v.width] + let select = [] + let month = b:calendar.month() + let ij = month.sub(self.get_months()[0]) + let [i, j] = [ij % self.x_months, ij / self.x_months] + let o = self.month_names_offset[j] + let sunsat = [] + if self.is_selected() + for x in range(calendar#week#week_count(month) * mh + v.offset) + let l = x ? (x > 1 ? w * 7 : self.day_names_len) : o[i * 2 + 1] - o[i * 2] + let offset = x ? ((x > 1 ? w * 7 : self.day_names_len) + v.pad) * i : o[i * 2] + if x != mh + call add(select, calendar#text#new(l - (self.view.width - 2), offset, h * j + x, 'Select')) + endif + endfor + call add(select, calendar#text#new(0, o[i * 2], h * j, 'Cursor')) + let sun = self.sun_position[ij] + for j in range(sun[2] - sun[1] + mh - 1) + call add(sunsat, calendar#text#new(2, sun[0], sun[1] + j + 1, '')) + endfor + let sat = self.sat_position[ij] + for j in range(sat[2] - sat[1] + mh - 1) + call add(sunsat, calendar#text#new(2, sat[0], sat[1] + j + 1, '')) + endfor + endif + return deepcopy(self.days) + select + deepcopy(self.syntax) + sunsat + deepcopy(self.top_syntax) +endfunction + +function! s:instance.action(action) dict abort + let month = b:calendar.month() + let months = self.get_months() + let ij = month.sub(months[0]) + let [x, y] = [self.x_months, self.y_months] + let [i, j] = [ij % x, ij / x] + if a:action ==# 'left' + call b:calendar.move_month(self.is_full() ? max([-v:count1, - i]) : -v:count1 * y) + elseif a:action ==# 'right' + call b:calendar.move_month(self.is_full() ? min([v:count1, x - 1 - i]) : v:count1 * y) + elseif index(['prev', 'next', 'space', 'add', 'subtract'], a:action) >= 0 + call b:calendar.move_month(v:count1 * (a:action ==# 'prev' || a:action ==# 'subtract' ? -1 : 1)) + elseif index(['down', 'up', 'scroll_down', 'scroll_up'], a:action) >= 0 + call b:calendar.move_month(v:count1 * (a:action =~# 'down' ? 1 : -1) * x) + elseif index(['plus', 'minus'], a:action) >= 0 + call b:calendar.move_month(v:count1 * (a:action ==# 'plus' ? 1 : -1) * x - i) + elseif index(['down_big', 'up_big'], a:action) >= 0 + call b:calendar.move_month(v:count1 * (a:action ==# 'down_big' ? 1 : -1) * (self.is_full() ? x * 2 : len(months))) + elseif index(['down_large', 'up_large'], a:action) >= 0 + call b:calendar.move_year(v:count1 * (a:action ==# 'down_large' ? 1 : -1)) + elseif a:action ==# 'line_head' + call b:calendar.move_month(self.is_full() ? -i : -x * y / 2) + elseif a:action ==# 'line_middle' + call b:calendar.move_month(self.is_full() ? (x - 1) / 2 - i : 0) + elseif a:action ==# 'line_last' + call b:calendar.move_month(self.is_full() ? x - 1 - i : x * y / 2) + elseif a:action ==# 'bar' + call b:calendar.move_month(min([v:count1, x]) - (self.is_full() ? i + 1 : (x + 1) / 2)) + elseif a:action ==# 'first_line' || a:action ==# 'first_line_head' + call b:calendar.move_month(- ij) + elseif a:action ==# 'last_line' + call b:calendar.move_month(-month.sub(months[-x])) + elseif a:action ==# 'last_line_last' + call b:calendar.move_month(-month.sub(months[-1])) + elseif a:action ==# 'command_enter' && mode() ==# 'c' && getcmdtype() ==# ':' + let cmd = calendar#util#getcmdline() + if cmd =~# '^\s*\d\+\s*$' + let c = max([min([cmd * 1, 12]), 1]) + call b:calendar.move_month(c - month.get_month()) + return calendar#util#update_keys() + endif + endif +endfunction + +let s:super_constructor = calendar#constructor#view#new(s:instance) + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/constructor/view_textbox.vim b/bundle/calendar.vim/autoload/calendar/constructor/view_textbox.vim new file mode 100644 index 000000000..2d15e2eea --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/constructor/view_textbox.vim @@ -0,0 +1,362 @@ +" ============================================================================= +" Filename: autoload/calendar/constructor/view_textbox.vim +" Author: itchyny +" License: MIT License +" Last Change: 2021/09/18 13:37:00. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +function! calendar#constructor#view_textbox#new(instance) abort + return extend({ 'instance': a:instance }, s:constructor) +endfunction + +let s:constructor = {} + +function! s:constructor.new(source) dict abort + return extend(extend(s:super_constructor.new(a:source), s:instance), self.instance) +endfunction + +let s:instance = {} +let s:instance._key = [] +let s:instance.__key = [] +let s:instance._texts = [] +let s:instance.select = 0 +let s:instance.noindex = [] +let s:instance._select_title = 0 +let s:instance.syntax = [] +let s:instance.length = 0 +let s:instance._current_contents = {} +let s:instance._prev_contents = {} +let s:instance._prevprev_contents = {} +let s:instance._next_contents = {} +let s:instance._current_group_id = '' +let s:instance._nocontents = 1 + +function! s:instance.width() dict abort + let frame = calendar#setting#frame() + let width = calendar#string#strdisplaywidth(frame.vertical) + return self.maxwidth() / width * width + 2 +endfunction + +function! s:instance.contents() dict abort + if self._key == [self.is_selected(), self.select, self.sizex(), self.sizey(), get(self, 'min_index'), get(self, 'max_index')] + self.get_key() + return deepcopy(self._texts) + endif + let s = [] + let frame = calendar#setting#frame() + let width = calendar#string#strdisplaywidth(frame.vertical) + let flen = len(frame.vertical) + let top = frame.topleft . repeat(frame.horizontal, (self.sizex() - 2) / width - 2) . frame.topright + let bottom = frame.bottomleft . repeat(frame.horizontal, (self.sizex() - 2) / width - 2) . frame.bottomright + let w = self.sizex() - 4 - width * 2 + let sizey = self.sizey() - 1 + let self.cnt = self.get_contents() + let self.length = len(self.cnt) + if len(self.cnt) + for i in range(min([len(self.cnt) - self.min_index, sizey])) + call add(s, self.cnt[self.min_index + i]) + endfor + endif + if len(s) < sizey + for i in range(sizey - len(s)) + call add(s, '') + endfor + else + let s = s[:sizey] + endif + call map(s, 'calendar#string#truncate(v:val, w)') + let texts = map(range(len(s)), 'calendar#text#new(" " . frame.vertical . " " . s[v:val] . " " . frame.vertical . " ", 0, v:val + 1, "")') + call insert(texts, calendar#text#new(' ' . top . ' ', 0, 0, ''), 0) + call add(texts, calendar#text#new(' ' . bottom . ' ', 0, len(s), '')) + let selsyn = '' + for [i, syn] in self.syntax + if self.min_index <= i && i + 1 < self.min_index + sizey + let len = len(s[i - self.min_index]) + 2 + call add(texts, calendar#text#new(len, 1 + flen, 1 + i - self.min_index, syn)) + if i == self.select + let selsyn = syn + endif + endif + endfor + if self.is_selected() + if self.min_index <= self.select && self.select < self.min_index + sizey + if self._select_line + let len = len(s[self.select - self.min_index]) + 2 + call add(texts, calendar#text#new(len, 1 + flen, 1 + self.select - self.min_index, selsyn . 'Select')) + endif + endif + call add(texts, calendar#text#new(0, 1 + flen, 1 + self.select - self.min_index, 'Cursor')) + endif + let self._texts = deepcopy(texts) + let self._key = [self.is_selected(), self.select, self.sizex(), self.sizey(), get(self, 'min_index'), get(self, 'max_index')] + self.get_key() + return texts +endfunction + +function! s:instance.get_key() dict abort + return [] +endfunction + +function! s:instance.get_contents() dict abort + if self.__key == [self.select, self.sizex(), self.sizey(), get(self, 'min_index'), get(self, 'max_index')] + self.get_key() + return self.cnt + endif + let self.noindex = [] + let self.syntax = [] + let cnt = [] + let frame = calendar#setting#frame() + let width = calendar#string#strdisplaywidth(frame.vertical) + let cnts = self.get_raw_contents() + let w = self.sizex() - width * 2 + if len(cnts) + let self._current_contents = {} + let self._prev_contents = {} + let self._prevprev_contents = {} + let self._next_contents = {} + for j in range(len(cnts)) + let t = cnts[j] + if len(cnt) + if !self._select_title + call add(self.noindex, len(cnt)) + endif + call add(cnt, '') + endif + if !self._select_title + call add(self.noindex, len(cnt)) + endif + if len(cnt) == self.select + let self._current_contents = { 'title': t.title } + endif + call add(cnt, repeat(' ', max([(self.sizex() - 4 - width * 2 - calendar#string#strdisplaywidth(t.title)) / 2, 0])) . t.title) + if !self._select_title + call add(self.noindex, len(cnt)) + endif + call add(cnt, '') + while index(self.noindex, self.select) >= 0 + let self.select += 1 + endwhile + if j == len(cnts) - 1 + let self.select = min([self.select, len(cnt) + len(t.items) - 1]) + endif + for tt in t.items + let lencnt = len(cnt) + if lencnt == self.select - 1 + let self._prev_contents = deepcopy(tt) + elseif lencnt == self.select - 2 + let self._prevprev_contents = deepcopy(tt) + elseif lencnt == self.select + 1 + let self._next_contents = deepcopy(tt) + elseif lencnt == self.select + let self._current_contents = deepcopy(tt) + let self._current_group_id = get(t, 'id', '') + endif + if get(tt, 'status', '') ==# 'completed' + call add(self.syntax, [len(cnt), 'Comment']) + elseif has_key(tt, 'syntax') + call add(self.syntax, [len(cnt), tt.syntax]) + endif + call add(cnt, get(tt, 'prefix', '') . get(tt, 'title', get(tt, 'summary', ''))) + endfor + endfor + if self._nocontents && has_key(self, 'min_index') && has_key(self, 'max_index') + unlet! self.min_index self.max_index + endif + if self._current_group_id == '' + let self._current_group_id = get(cnts[0], 'id', '') + endif + let [self.min_index, self.max_index] = self.min_max_index(len(cnt)) + let self._nocontents = 0 + else + let [self.min_index, self.max_index] = [0, 0] + let self._nocontents = 1 + let self.select = 0 + let self._prev_contents = {} + let self._prevprev_contents = {} + let self._next_contents = {} + let self._current_contents = {} + let self._current_group_id = '' + endif + let self.__key = [self.select, self.sizex(), self.sizey(), get(self, 'min_index'), get(self, 'max_index')] + self.get_key() + return cnt +endfunction + +function! s:instance.min_max_index(length) dict abort + let height = self.sizey() - 2 + let length = max([a:length, height]) + if has_key(self, 'min_index') + if self.select < self.min_index + let min = self.select + elseif self.select >= self.max_index + let min = self.min_index + self.select - self.max_index + else + let min = self.min_index + endif + else + let min = self.select - height / 2 + 2 + endif + let min = max([min, 0]) + let max = min([min + height - 1, length - 1]) + let min = max([max - height + 1, 0]) + let max = min([min + height - 1, length - 1]) + return [min, max] +endfunction + +function! s:instance.move_select(diff) dict abort + let self.select = max([min([self.select + a:diff, self.length - 1]), 0]) + let diff = a:diff > 0 ? 1 : -1 + while index(self.noindex, self.select) >= 0 + if self.select < 3 + let self.min_index = - self.length + let diff = 1 + endif + let self.select += diff + endwhile + let self.select = max([min([self.select, self.length - 1]), 0]) + let self.__updated = 1 + let [self.min_index, self.max_index] = self.min_max_index(self.length) +endfunction + +function! s:instance.current_contents() dict abort + return self._current_contents +endfunction + +function! s:instance.prev_contents() dict abort + return self._prev_contents +endfunction + +function! s:instance.prevprev_contents() dict abort + return self._prevprev_contents +endfunction + +function! s:instance.next_contents() dict abort + return self._next_contents +endfunction + +function! s:instance.current_group_id() dict abort + return self._current_group_id +endfunction + +function! s:instance._action(action) dict abort + let hour = self.select + let self.__updated = 0 + let [select, min_index, max_index] = [self.select, self.min_index, self.max_index] + if index(['down', 'up'], a:action) >= 0 + call self.move_select(v:count1 * (a:action ==# 'down' ? 1 : -1)) + elseif index(['down_big', 'up_big'], a:action) >= 0 + let diff = self.max_index - self.min_index + let dir = a:action ==# 'down_big' ? 1 : -1 + let di = max([min([v:count1 * dir * diff * 2 / 3, self.length - 1 - hour]), - hour]) + if dir > 0 + let self.min_index = self.min_index + v:count1 * dir * diff + let self.max_index = self.min_index + diff + else + let self.max_index = self.max_index + v:count1 * dir * diff + let self.min_index = self.max_index - diff + endif + call self.move_select(di) + elseif index(['down_large', 'up_large'], a:action) >= 0 + let diff = self.max_index - self.min_index + let dir = a:action ==# 'down_large' ? 1 : -1 + let di = max([min([(dir > 0 ? self.max_index : self.min_index) - hour + (v:count1 - 1) * dir * diff, self.length - 1 - hour]), - hour]) + if dir > 0 + let self.min_index = self.min_index + v:count1 * dir * diff + let self.max_index = self.min_index + diff + else + let self.max_index = self.max_index + v:count1 * dir * diff + let self.min_index = self.max_index - diff + endif + call self.move_select(di) + elseif a:action ==# 'first_line' || a:action ==# 'first_line_head' || (a:action ==# 'last_line' && v:count) + call self.move_select((v:count ? min([v:count1, self.length - 1]) : 0) - hour) + elseif a:action ==# 'last_line' + call self.move_select((v:count ? max([v:count1, self.length - 1]) : self.length - 1) - hour) + elseif a:action ==# 'last_line_last' + call self.move_select((v:count ? max([v:count1, self.length - 1]) : self.length - 1) - hour) + elseif index(['scroll_down', 'scroll_up'], a:action) >= 0 + let diff = v:count1 * (a:action =~# 'down' ? 1 : -1) + let old_indeces = [self.min_index, self.max_index] + let self.min_index += diff + let self.max_index += diff + let new_indeces = self.min_max_index(self.length) + if old_indeces == new_indeces + call self.move_select(diff) + endif + elseif index(['scroll_top_head', 'scroll_top', 'scroll_bottom_head', 'scroll_bottom', 'scroll_center_head', 'scroll_center'], a:action) >= 0 + let diff = a:action =~# 'center' ? hour - (self.max_index - self.min_index) / 2 + 1 - self.min_index : (self.length - 1) * (a:action =~# 'top' ? 1 : -1) + let self.min_index += diff + let self.max_index += diff + elseif a:action ==# 'status' + let message = get(self.current_contents(), 'title', get(self.current_contents(), 'summary', '')) + call calendar#echo#message(message) + return 1 + elseif index(['yank', 'yank_line'], a:action) >= 0 + call self.yank() + return 1 + elseif index(['delete', 'delete_line'], a:action) >= 0 + if calendar#setting#get('yank_deleting') + call self.yank() + endif + return 1 + elseif a:action ==# 'enter' + let url = get(self.current_contents(), 'htmlLink', '') + if url !=# '' + call calendar#webapi#open_url(url) + endif + elseif a:action ==# 'command_enter' && mode() ==# 'c' && getcmdtype() ==# ':' + let cmd = calendar#util#getcmdline() + if cmd =~# '\v^\s*\d+\s*$' + let c = max([min([matchstr(cmd, '\d\+') * 1 - 1, self.length - 1]), 0]) + let idxes = filter(range(self.length), 'index(self.noindex, v:val) < 0') + call self.move_select(get(idxes, c, get(idxes, -1, 0)) - hour) + return calendar#util#update_keys() + endif + elseif a:action ==# 'command_enter' && mode() ==# 'c' && (getcmdtype() ==# '/' || getcmdtype() ==# '?') + \ || a:action ==# 'next_match' || a:action ==# 'prev_match' + let iscmd = a:action ==# 'command_enter' + let pattern = iscmd ? getcmdline() : @/ + if iscmd && getcmdtype() ==# '/' || a:action ==# 'next_match' && v:searchforward + \ || a:action ==# 'prev_match' && !v:searchforward + let indexes = range(self.select + 1 - iscmd, self.length - 1) + range(self.select + 1) + let status = '/' . pattern + else + let indexes = range(self.select - 1 + iscmd, 0, -1) + range(self.length - 1, self.select, -1) + let status = '?' . pattern + endif + let exitvalue = iscmd ? "\:\silent call b:calendar.update()\" + \ . ":\silent let v:searchforward=" . (getcmdtype() ==# '/') . "\" + \ . ":\echo " . string(status) . "\" : 0 + if iscmd + let @/ = pattern + else + echo status + endif + try + for i in indexes + if self.cnt[i] =~ pattern " do not use =~# (use 'ignorecase') + call self.move_select(i - self.select) + return exitvalue + endif + endfor + catch + endtry + return exitvalue + endif + if self.__updated && [select, max_index] == [self.select, self.max_index] && (min_index == self.min_index || !min_index) + return '' + endif +endfunction + +function! s:instance.yank() dict abort + let message = get(self.current_contents(), 'title', get(self.current_contents(), 'summary', '')) + call calendar#util#yank(message) +endfunction + +function! s:instance.action(action) dict abort + return self._action(a:action) +endfunction + +let s:super_constructor = calendar#constructor#view#new(s:instance) + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/constructor/view_ymd.vim b/bundle/calendar.vim/autoload/calendar/constructor/view_ymd.vim new file mode 100644 index 000000000..101867b8a --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/constructor/view_ymd.vim @@ -0,0 +1,127 @@ +" ============================================================================= +" Filename: autoload/calendar/constructor/view_ymd.vim +" Author: itchyny +" License: MIT License +" Last Change: 2017/07/02 08:42:35. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +function! calendar#constructor#view_ymd#new(instance) abort + return extend({ 'instance': a:instance }, s:constructor) +endfunction + +let s:constructor = {} + +function! s:constructor.new(source) dict abort + let instance = extend(extend(s:super_constructor.new(a:source), s:instance), self.instance) + let iday = index(instance.ymd, 'day') + let imonth = index(instance.ymd, 'month') + let iyear = index(instance.ymd, 'year') + let instance.select_index = iday >= 0 ? iday : imonth >= 0 ? imonth : iyear + return instance +endfunction + +let s:instance = {} + +function! s:instance.width() dict abort + return len(self.contents()[0].s) +endfunction + +function! s:instance.height() dict abort + return 1 +endfunction + +function! s:sum(l) abort + let n = 0 + for i in a:l + let n += i + endfor + return n +endfunction + +function! s:instance.contents() dict abort + let y = b:calendar.month().get_year() + let year = y > 0 ? string(y) : (1 - y) . ' BC' + let use_month_name = calendar#setting#get('date_month_name') + let use_full_month_name = calendar#setting#get('date_full_month_name') + if use_full_month_name + let month = calendar#message#get('month_name_long')[b:calendar.month().get_month() - 1] + elseif use_month_name + let month = calendar#message#get('month_name')[b:calendar.month().get_month() - 1] + else + let month = printf('%2d', b:calendar.month().get_month()) + endif + let day = printf('%2d', b:calendar.day().get_day()) + let sepa = substitute(printf(' %s ', calendar#setting#get('date_separator')), '\s\+', ' ', 'g') + let texts = map(copy(self.ymd), "get({ 'year': year, 'month': month, 'day': day }, v:val)") + let t = '' + let separator = [] + for i in range(len(texts)) + if i + let sep = use_month_name && (self.ymd[i - 1] ==# 'month' && self.ymd[i] ==# 'day' || self.ymd[i - 1] ==# 'day' && self.ymd[i] ==# 'month') ? ' ' : sepa + else + let sep = '' + endif + call add(separator, sep) + let t .= sep . texts[i] + endfor + let text = calendar#text#new(t, 0, 0, '') + if self.is_selected() + let separatorlen = map(copy(separator), 'len(v:val)') + let length = map(copy(self.ymd), "get({ 'year': len(year), 'month': len(month), 'day': len(day) }, v:val)") + let position = map(range(len(length)), 's:sum((v:val ? length[:(v:val - 1)] : []) + (separatorlen[:(v:val)]))') + let select = calendar#text#new(length[self.select_index], position[self.select_index], 0, 'Select') + let cursor = calendar#text#new(0, length[self.select_index] + position[self.select_index], 0, 'Cursor') + return [text, select, cursor] + else + return [text] + endif +endfunction + +function! s:instance.action(action) dict abort + if index(['left', 'prev', 'line_head', 'first_line', 'last_line' ], a:action) >= 0 + let self.select_index = max([self.select_index - 1, 0]) + elseif index(['right', 'next', 'line_last', 'last_line_last'], a:action) >= 0 + let self.select_index = min([self.select_index + 1, len(self.ymd) - 1]) + elseif index(['down', 'up', 'add', 'subtract', 'plus', 'minus', 'scroll_down', 'scroll_up'], a:action) >= 0 + let diff = v:count1 * (index(['down', 'add', 'plus', 'scroll_down'], a:action) >= 0 ? 1 : -1) + call b:calendar['move_' . self.ymd[self.select_index]](diff) + elseif index(['down_big', 'up_big'], a:action) >= 0 + let diff = v:count1 * (a:action ==# 'down_big' ? 1 : -1) + let move_big = { 'year': 10, 'month': 3, 'day': 7 } + call b:calendar['move_' . self.ymd[self.select_index]](diff * move_big[self.ymd[self.select_index]]) + elseif index(['down_large', 'up_large'], a:action) >= 0 + let diff = v:count1 * (a:action ==# 'down_large' ? 1 : -1) + let move_large = { 'year': 100, 'month': 6, 'day': 14 } + call b:calendar['move_' . self.ymd[self.select_index]](diff * move_large[self.ymd[self.select_index]]) + elseif a:action ==# 'bar' + let self.select_index = max([min([v:count1 - 1, len(self.ymd) - 1]), 0]) + elseif a:action ==# 'space' + let self.select_index = (self.select_index + 1) % len(self.ymd) + elseif a:action ==# 'command_enter' && mode() ==# 'c' && getcmdtype() ==# ':' + let cmd = calendar#util#getcmdline() + if cmd =~# '\v^\s*\d+\s*$' + let c = matchstr(cmd, '\v\d+') * 1 + if self.ymd[self.select_index] ==# 'day' + let month = b:calendar.month() + let [y, m] = month.get_ym() + let c = max([min([c, month.last_day().get_day()]), month.head_day().get_day()]) + call b:calendar.move_day(b:calendar.day().new(y, m, c).sub(b:calendar.day())) + elseif self.ymd[self.select_index] ==# 'month' + let month = b:calendar.month().get_month() + let c = max([min([c, 12]), 1]) + call b:calendar.move_month(c - month) + elseif self.ymd[self.select_index] ==# 'year' + call b:calendar.move_year(c - b:calendar.month().get_year()) + endif + return calendar#util#update_keys() + endif + endif +endfunction + +let s:super_constructor = calendar#constructor#view#new(s:instance) + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/constructor/year.vim b/bundle/calendar.vim/autoload/calendar/constructor/year.vim new file mode 100644 index 000000000..169f4c8ea --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/constructor/year.vim @@ -0,0 +1,117 @@ +" ============================================================================= +" Filename: autoload/calendar/constructor/year.vim +" Author: itchyny +" License: MIT License +" Last Change: 2015/03/29 06:28:04. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +function! calendar#constructor#year#new(day_constructor) abort + return extend({ 'day_constructor': a:day_constructor, 'cache': {} }, s:constructor) +endfunction + +let s:constructor = {} + +function! s:constructor.new(y) dict abort + let instance = copy(s:instance) + let instance.day_constructor = self.day_constructor + let instance._y = a:y + let instance.constructor = self + return instance +endfunction + +let s:instance = {} + +function! s:instance.new(y) dict abort + return self.constructor.new(a:y) +endfunction + +function! s:instance.add(diff) dict abort + return self.new(self.get_y() + a:diff) +endfunction + +function! s:instance.sub(year) dict abort + return self.get_y() - a:year.get_y() +endfunction + +function! s:instance.eq(year) dict abort + return self.get_y() == a:year.get_y() +endfunction + +function! s:instance.is_valid() dict abort + return self.head_day().is_valid() && self.last_day().is_valid() +endfunction + +function! s:instance.get_y() dict abort + if has_key(self, 'y') | return self.y | endif + let self.y = self.head_day().get_ymd()[0] + return self.y +endfunction + +function! s:instance.get_year() dict abort + return self.get_y() +endfunction + +function! s:instance.get_month() dict abort + return self.head_day().get_month() +endfunction + +function! s:instance.get_day() dict abort + return self.head_day().get_day() +endfunction + +function! s:instance.head_day() dict abort + if has_key(self, '_head_day') | return self._head_day | endif + let self._head_day = self.day_constructor.new(self._y, 1, 1) + return self._head_day +endfunction + +function! s:instance.last_day() dict abort + if has_key(self, '_last_day') | return self._last_day | endif + let self._last_day = self.day_constructor.new(self._y + 1, 1, 1).add(-1) + return self._last_day +endfunction + +function! s:instance.head_month() dict abort + if has_key(self, '_head_month') | return self._head_month | endif + let self._head_month = self.head_day().month() + return self._head_month +endfunction + +function! s:instance.last_month() dict abort + if has_key(self, '_last_month') | return self._last_month | endif + let self._last_month = self.last_day().month() + return self._last_month +endfunction + +function! s:instance.days() dict abort + if has_key(self, '_days') | return self._days | endif + let self._days = self.last_day().sub(self.head_day()) + 1 + return self._days +endfunction + +function! s:instance.get_months() dict abort + if has_key(self, '__months') | return self.__months | endif + if has_key(self.constructor.cache, self.get_y()) | return self.constructor.cache[self.get_y()] | endif + let months = [] + call add(months, self.head_month()) + while !self.last_month().eq(months[-1]) + call add(months, months[-1].add(1)) + endwhile + let self.__months = months + let self.constructor.cache[self.get_y()] = months + return months +endfunction + +function! s:instance.day() dict abort + return self.head_day() +endfunction + +function! s:instance.month() dict abort + return self.head_month() +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/controller.vim b/bundle/calendar.vim/autoload/calendar/controller.vim new file mode 100644 index 000000000..80c703b12 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/controller.vim @@ -0,0 +1,280 @@ +" ============================================================================= +" Filename: autoload/calendar/controller.vim +" Author: itchyny +" License: MIT License +" Last Change: 2021/09/14 13:07:41. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +" Calendar controller. This object is the top-level object, b:calendar. +function! calendar#controller#new() abort + let self = deepcopy(s:self) + let self.model = calendar#model#new() + let self.view = calendar#view#new() + let self.task = calendar#task#new() + let self.event = calendar#event#new() + let self.mark = calendar#mark#new() + return self +endfunction + +let s:self = {} + +let s:self.pos = [0, 0] + +let s:self.cursor_pos = [0, 0] + +let s:self.mode = '' + +let s:self.action_name = '' + +let s:self.defaultsyntaxnames = ['Select', 'Sunday', 'Saturday', + \ 'TodaySunday', 'TodaySaturday', 'Today', + \ 'OtherMonth', 'OtherMonthSelect', 'DayTitle', 'SundayTitle', 'SaturdayTitle', + \ 'NormalSpace', 'Comment', 'CommentSelect'] + +function! s:self.time() dict abort + return self.model.time() +endfunction + +function! s:self.set_time(time) dict abort + return self.model.set_time(a:time) +endfunction + +function! s:self.second() dict abort + return self.model.second() +endfunction + +function! s:self.minute() dict abort + return self.model.minute() +endfunction + +function! s:self.hour() dict abort + return self.model.hour() +endfunction + +function! s:self.move_second(diff) dict abort + call self.model.move_second(a:diff) +endfunction + +function! s:self.move_minute(diff) dict abort + call self.model.move_minute(a:diff) +endfunction + +function! s:self.move_hour(diff) dict abort + call self.model.move_hour(a:diff) +endfunction + +function! s:self.day() dict abort + return self.model.day() +endfunction + +function! s:self.set_day(day) dict abort + return self.model.set_day(a:day) +endfunction + +function! s:self.month() dict abort + return self.model.month() +endfunction + +function! s:self.set_month() dict abort + return self.model.set_month(self.day().month()) +endfunction + +function! s:self.year() dict abort + return self.model.year() +endfunction + +function! s:self.get_days() dict abort + return self.model.get_days() +endfunction + +function! s:self.move_day(diff) dict abort + call self.model.move_day(a:diff) +endfunction + +function! s:self.move_month(diff) dict abort + call self.model.move_month(a:diff) +endfunction + +function! s:self.move_year(diff) dict abort + call self.model.move_year(a:diff) +endfunction + +function! s:self.start_visual() dict abort + call self.model.start_visual() +endfunction + +function! s:self.start_line_visual() dict abort + call self.model.start_line_visual() +endfunction + +function! s:self.start_block_visual() dict abort + call self.model.start_block_visual() +endfunction + +function! s:self.exit_visual() dict abort + call self.model.exit_visual() +endfunction + +function! s:self.visual_mode() dict abort + return self.model.visual_mode() +endfunction + +function! s:self.is_visual() dict abort + return self.model.is_visual() +endfunction + +function! s:self.is_line_visual() dict abort + return self.model.is_line_visual() +endfunction + +function! s:self.is_block_visual() dict abort + return self.model.is_block_visual() +endfunction + +function! s:self.visual_start_day() dict abort + return self.model.visual_start_day() +endfunction + +function! s:self.visual_start_time() dict abort + return self.model.visual_start_time() +endfunction + +function! s:self.go(day) dict abort + call self.set_day(a:day) + call self.set_month() + call self.update() +endfunction + +function! s:self.prepare() dict abort + let [self.winheight, self.winwidth] = [calendar#util#winheight(), calendar#util#winwidth()] + call calendar#mapping#new() + call calendar#autocmd#new() + call calendar#setlocal#new() +endfunction + +function! s:self.update() dict abort + call self.prepare() + call self.redraw(0) +endfunction + +function! s:self.update_force() dict abort + call self.prepare() + call self.redraw(1) +endfunction + +function! s:self.update_force_redraw() dict abort + call self.event.clear_cache() + call self.task.clear_cache() + call self.prepare() + call self.redraw(1, 1) +endfunction + +function! s:self.update_if_resized() dict abort + if self.winheight != calendar#util#winheight() || self.winwidth != calendar#util#winwidth() + call self.update_force_redraw() + endif +endfunction + +function! s:self.clear() dict abort + for name in self.defaultsyntaxnames + get(b:calendar, 'syntaxnames', []) + exec 'silent! syntax clear Calendar' . name + endfor +endfunction + +function! s:self.redraw(...) dict abort + if histget(':', -1) ==# 'silent call b:calendar.update()' + silent! call histdel(':', -1) + endif + let u = self.view.gather(a:0 ? a:1 : 0) + if type(u) != type([]) + return + endif + call calendar#setlocal#modifiable() + silent % delete _ + if a:0 > 1 && a:2 + redraw + endif + call self.clear() + call setline(1, map(range(calendar#util#winheight()), 'u[v:val].s')) + let xs = {} + let names = [] + for t in u + for s in t.syn + let name = s[0] + if name !=# '' && s[1] >= 0 && s[2] >= 0 + if name ==# 'Cursor' + let self.pos = [s[2], s[1]] + else + if !has_key(xs, name) + let xs[name] = [] + call add(names, name) + endif + call add(xs[name], s[4] ? [s[1], s[1] + s[4] + 1, s[2] + 1, s[3] + 1] : [s[1] + 1, s[2] + 1, s[3] + 1]) + endif + endif + endfor + endfor + for name in names + execute 'syntax match Calendar' . name . ' /\v' . join(map(xs[name], 'len(v:val) > 3' + \.' ? "%>" . v:val[0] . "l%<" . v:val[1] . "l%" . v:val[2] . "c.*%" . v:val[3] . "c"' + \.' : "%" . v:val[0] . "l%" . v:val[1] . "c.*%" . v:val[2] . "c"'), '|') . '/' + endfor + call self.cursor() + call calendar#setlocal#nomodifiable() +endfunction + +function! s:self.cursor() dict abort + let b:calendar.cursor_pos = [self.pos[1] + 1, self.pos[0] + 1] + call cursor(b:calendar.cursor_pos[0], b:calendar.cursor_pos[1]) +endfunction + +function! s:self.cursor_moved() dict abort + if [line('.'), col('.')] == b:calendar.cursor_pos + return + else + let [l, c] = [line('.'), col('.')] + let [pl, pc] = b:calendar.cursor_pos + let g = getline('.') + let [wp, wn, wg] = map([getline(pl)[:pc - 2], g[:c - 2], g], 'calendar#string#strdisplaywidth(v:val)') + if pl == l + call self.action(wg <= wn * 2 && wn * 2 <= wg + 3 ? 'line_middle' + \ : g[:c - 2] =~? '^\s*$' ? 'line_head' + \ : len(g) == c ? 'line_last' + \ : pc < c ? 'right' + \ : 'left') + elseif wp - wn < 2 && wp - wn > -2 + call self.action(pl < l ? 'down' : 'up') + elseif l == 1 && (c > 2 && getline(1)[:c - 2] =~? '^ *$' || c <= 2) + call self.action('first_line') + elseif l == line('$') && c > 2 && getline(1)[:c - 2] =~? '^ *$' + call self.action('last_line_last') + endif + endif +endfunction + +function! s:self.action(action) dict abort + let action = a:action + if index([ 'delete', 'yank', 'change' ], action) >= 0 + if self.mode ==# action + let self.mode = '' + let action .= '_line' + else + let self.mode = action + return + endif + else + let self.mode = '' + endif + let self.action_name = action + let ret = self.view.action(action) + if type(ret) == type(0) && ret == 0 + call self.update() + endif + return ret +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/countcache.vim b/bundle/calendar.vim/autoload/calendar/countcache.vim new file mode 100644 index 000000000..aedcd5bc1 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/countcache.vim @@ -0,0 +1,88 @@ +" ============================================================================= +" Filename: autoload/calendar/countcache.vim +" Author: itchyny +" License: MIT License +" Last Change: 2020/11/19 07:40:05. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +" CountCache object, caching anything with countdown. +" Caching is imporant for speeding up. However, storing everything causes the +" cache to grow bigger and bigger. For efficient caching, this CountCache object +" is used. Basically, data are stored with numbers. +" [ num, data ] +" The number refers to how many times the data is referenced to. And when saving +" to the cache file, data are saved if the data was referenced many times enough. +" When restoring the data from the cache file, all the counts are subtracted +" one, so that data will disappear if it is not referenced to for a long time. + +let s:cache = calendar#cache#new('countcache') +let s:caches = [] + +function! calendar#countcache#new(name) abort + let self = extend(copy(s:self), { 'name': a:name }) + let cache = s:cache.get(a:name) + " When restoring from the cache file, negate each count by 1. + " Also, keep the number small (50 in max) so that the number will not overflow. + let self.cache = type(cache) == type({}) ? map(cache, '[min([v:val[0] - 1, 50]), v:val[1]]') : {} + call add(s:caches, self) + return self +endfunction + +let s:saveflag = {} + +let s:count = 0 + +" Saving the cache to the cache file. +function! calendar#countcache#save() abort + if s:count < 10 + let s:count += 1 + return + endif + let s:count = 0 + if exists('s:reltime') && has('reltime') + let time = split(split(reltimestr(reltime(s:reltime)))[0], '\.') + if time[0] < 60 + return + endif + endif + for c in s:caches + if get(s:saveflag, c.name, 1) + call s:cache.save(c.name, filter(c.cache, 'v:val[0] > 29')) + let s:saveflag[c.name] = 0 + endif + endfor + if has('reltime') + let s:reltime = reltime() + endif +endfunction + +augroup CalendarCountCache + autocmd! + autocmd CursorHold * call calendar#countcache#save() +augroup END + +let s:self = {} + +" Check if the key is found in the cache. +function! s:self.has_key(k) dict abort + return has_key(self.cache, a:k) +endfunction + +" Be sure to check has_key before getting the data. +function! s:self.get(k) dict abort + let self.cache[a:k][0] += 1 + return self.cache[a:k][1] +endfunction + +" Save a data with a key. +function! s:self.save(k, v) dict abort + let self.cache[a:k] = [ get(self.cache, a:k, [0])[0] + 1, a:v ] + let s:saveflag[self.name] = 1 + return a:v +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/day.vim b/bundle/calendar.vim/autoload/calendar/day.vim new file mode 100644 index 000000000..a4fb2e86a --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/day.vim @@ -0,0 +1,78 @@ +" ============================================================================= +" Filename: autoload/calendar/day.vim +" Author: itchyny +" License: MIT License +" Last Change: 2015/03/29 06:29:20. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +" Day object switching the calendar based on the user's setting. +function! calendar#day#new(y, m, d) abort + return calendar#day#{calendar#setting#get('calendar')}#new(a:y, a:m, a:d) +endfunction + +" Day object from mjd. +function! calendar#day#new_mjd(mjd) abort + return calendar#day#{calendar#setting#get('calendar')}#new_mjd(a:mjd) +endfunction + +" Today. +function! calendar#day#today() abort + return calendar#day#new_mjd(calendar#day#today_mjd()) +endfunction + +" Today's mjd. +function! calendar#day#today_mjd() abort + let [y, m, d] = s:ymd() + if has_key(s:, '_y') && s:_y == [y, m, d] + return s:_m + endif + let s:_y = [y, m, d] + let s:_m = calendar#day#gregorian#new(y, m, d).mjd + return s:_m +endfunction + +" Today's [ year, month, day ]. +if exists('*strftime') + function! s:ymd() abort + return [strftime('%Y') * 1, strftime('%m') * 1, strftime('%d') * 1] + endfunction +else + function! s:ymd() abort + return [system('date "+%Y"') * 1, system('date "+%m"') * 1, system('date "+%d"') * 1] + endfunction +endif + +" Join the year, month and day using the endian, separator settings. +function! calendar#day#join_date(ymd) abort + let endian = calendar#setting#get('date_endian') + let use_month_name = calendar#setting#get('date_month_name') + let sep1 = calendar#setting#get('date_separator') + let sep2 = use_month_name ? '' : sep1 + let ymd = a:ymd + if len(a:ymd) == 3 + let [y, m, d] = a:ymd + let mm = use_month_name ? calendar#message#get('month_name')[m - 1] : m + if endian ==# 'big' + let ymd = [y, sep1, mm, sep2, d] + elseif endian ==# 'middle' + let ymd = [mm, sep2, d, sep1, y] + else + let ymd = [d, sep2, mm, sep1, y] + endif + elseif len(a:ymd) == 2 + let [m, d] = a:ymd + let mm = use_month_name ? calendar#message#get('month_name')[m - 1] : m + if endian ==# 'big' || endian ==# 'middle' + let ymd = [mm, sep2, d] + else + let ymd = [d, sep2, mm] + endif + endif + return join(ymd, '') +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/day/austria.vim b/bundle/calendar.vim/autoload/calendar/day/austria.vim new file mode 100644 index 000000000..2992cdaa7 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/day/austria.vim @@ -0,0 +1,27 @@ +" ============================================================================= +" Filename: autoload/calendar/day/austria.vim +" Author: itchyny +" License: MIT License +" Last Change: 2015/03/29 06:28:32. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +" Brixen, Salzburg and Tyrol +let s:constructor = calendar#constructor#day_hybrid#new(1583, 10, 16) + +function! calendar#day#austria#new(y, m, d) abort + return s:constructor.new(a:y, a:m, a:d) +endfunction + +function! calendar#day#austria#new_mjd(mjd) abort + return s:constructor.new_mjd(a:mjd) +endfunction + +function! calendar#day#austria#today() abort + return s:constructor.today() +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/day/austriastyria.vim b/bundle/calendar.vim/autoload/calendar/day/austriastyria.vim new file mode 100644 index 000000000..b0757446d --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/day/austriastyria.vim @@ -0,0 +1,27 @@ +" ============================================================================= +" Filename: autoload/calendar/day/austriastyria.vim +" Author: itchyny +" License: MIT License +" Last Change: 2015/03/29 06:28:34. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +" Carinthia and Styria +let s:constructor = calendar#constructor#day_hybrid#new(1583, 12, 25) + +function! calendar#day#austriastyria#new(y, m, d) abort + return s:constructor.new(a:y, a:m, a:d) +endfunction + +function! calendar#day#austriastyria#new_mjd(mjd) abort + return s:constructor.new_mjd(a:mjd) +endfunction + +function! calendar#day#austriastyria#today() abort + return s:constructor.today() +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/day/british.vim b/bundle/calendar.vim/autoload/calendar/day/british.vim new file mode 100644 index 000000000..b6cd14c9a --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/day/british.vim @@ -0,0 +1,26 @@ +" ============================================================================= +" Filename: autoload/calendar/day/british.vim +" Author: itchyny +" License: MIT License +" Last Change: 2015/03/29 06:28:36. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +let s:constructor = calendar#constructor#day_hybrid#new(1752, 9, 14) + +function! calendar#day#british#new(y, m, d) abort + return s:constructor.new(a:y, a:m, a:d) +endfunction + +function! calendar#day#british#new_mjd(mjd) abort + return s:constructor.new_mjd(a:mjd) +endfunction + +function! calendar#day#british#today() abort + return s:constructor.today() +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/day/bulgaria.vim b/bundle/calendar.vim/autoload/calendar/day/bulgaria.vim new file mode 100644 index 000000000..0bd834436 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/day/bulgaria.vim @@ -0,0 +1,26 @@ +" ============================================================================= +" Filename: autoload/calendar/day/bulgaria.vim +" Author: itchyny +" License: MIT License +" Last Change: 2015/03/29 06:28:37. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +let s:constructor = calendar#constructor#day_hybrid#new(1916, 4, 14) + +function! calendar#day#bulgaria#new(y, m, d) abort + return s:constructor.new(a:y, a:m, a:d) +endfunction + +function! calendar#day#bulgaria#new_mjd(mjd) abort + return s:constructor.new_mjd(a:mjd) +endfunction + +function! calendar#day#bulgaria#today() abort + return s:constructor.today() +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/day/canada.vim b/bundle/calendar.vim/autoload/calendar/day/canada.vim new file mode 100644 index 000000000..6a8e485f1 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/day/canada.vim @@ -0,0 +1,26 @@ +" ============================================================================= +" Filename: autoload/calendar/day/canada.vim +" Author: itchyny +" License: MIT License +" Last Change: 2015/03/29 06:28:39. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +let s:constructor = calendar#constructor#day_hybrid#new(1752, 9, 14) + +function! calendar#day#canada#new(y, m, d) abort + return s:constructor.new(a:y, a:m, a:d) +endfunction + +function! calendar#day#canada#new_mjd(mjd) abort + return s:constructor.new_mjd(a:mjd) +endfunction + +function! calendar#day#canada#today() abort + return s:constructor.today() +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/day/default.vim b/bundle/calendar.vim/autoload/calendar/day/default.vim new file mode 100644 index 000000000..4268b6b30 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/day/default.vim @@ -0,0 +1,26 @@ +" ============================================================================= +" Filename: autoload/calendar/day/default.vim +" Author: itchyny +" License: MIT License +" Last Change: 2015/03/29 06:28:40. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +let s:constructor = calendar#constructor#day_hybrid#new(1582, 10, 15) + +function! calendar#day#default#new(y, m, d) abort + return s:constructor.new(a:y, a:m, a:d) +endfunction + +function! calendar#day#default#new_mjd(mjd) abort + return s:constructor.new_mjd(a:mjd) +endfunction + +function! calendar#day#default#today() abort + return s:constructor.today() +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/day/estonia.vim b/bundle/calendar.vim/autoload/calendar/day/estonia.vim new file mode 100644 index 000000000..d2520a484 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/day/estonia.vim @@ -0,0 +1,26 @@ +" ============================================================================= +" Filename: autoload/calendar/day/estonia.vim +" Author: itchyny +" License: MIT License +" Last Change: 2015/03/29 06:28:42. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +let s:constructor = calendar#constructor#day_hybrid#new(1918, 2, 14) + +function! calendar#day#estonia#new(y, m, d) abort + return s:constructor.new(a:y, a:m, a:d) +endfunction + +function! calendar#day#estonia#new_mjd(mjd) abort + return s:constructor.new_mjd(a:mjd) +endfunction + +function! calendar#day#estonia#today() abort + return s:constructor.today() +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/day/france.vim b/bundle/calendar.vim/autoload/calendar/day/france.vim new file mode 100644 index 000000000..facfd6c2c --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/day/france.vim @@ -0,0 +1,26 @@ +" ============================================================================= +" Filename: autoload/calendar/day/france.vim +" Author: itchyny +" License: MIT License +" Last Change: 2015/03/29 06:28:44. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +let s:constructor = calendar#constructor#day_hybrid#new(1582, 12, 20) + +function! calendar#day#france#new(y, m, d) abort + return s:constructor.new(a:y, a:m, a:d) +endfunction + +function! calendar#day#france#new_mjd(mjd) abort + return s:constructor.new_mjd(a:mjd) +endfunction + +function! calendar#day#france#today() abort + return s:constructor.today() +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/day/germany.vim b/bundle/calendar.vim/autoload/calendar/day/germany.vim new file mode 100644 index 000000000..3f5051122 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/day/germany.vim @@ -0,0 +1,26 @@ +" ============================================================================= +" Filename: autoload/calendar/day/germany.vim +" Author: itchyny +" License: MIT License +" Last Change: 2015/03/29 06:28:45. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +let s:constructor = calendar#constructor#day_hybrid#new(1583, 1, 11) + +function! calendar#day#germany#new(y, m, d) abort + return s:constructor.new(a:y, a:m, a:d) +endfunction + +function! calendar#day#germany#new_mjd(mjd) abort + return s:constructor.new_mjd(a:mjd) +endfunction + +function! calendar#day#germany#today() abort + return s:constructor.today() +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/day/germanyprussia.vim b/bundle/calendar.vim/autoload/calendar/day/germanyprussia.vim new file mode 100644 index 000000000..a3a1df421 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/day/germanyprussia.vim @@ -0,0 +1,26 @@ +" ============================================================================= +" Filename: autoload/calendar/day/germanyprussia.vim +" Author: itchyny +" License: MIT License +" Last Change: 2015/03/29 06:28:47. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +let s:constructor = calendar#constructor#day_hybrid#new(1610, 9, 2) + +function! calendar#day#germanyprussia#new(y, m, d) abort + return s:constructor.new(a:y, a:m, a:d) +endfunction + +function! calendar#day#germanyprussia#new_mjd(mjd) abort + return s:constructor.new_mjd(a:mjd) +endfunction + +function! calendar#day#germanyprussia#today() abort + return s:constructor.today() +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/day/greece.vim b/bundle/calendar.vim/autoload/calendar/day/greece.vim new file mode 100644 index 000000000..26d9b440d --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/day/greece.vim @@ -0,0 +1,26 @@ +" ============================================================================= +" Filename: autoload/calendar/day/greece.vim +" Author: itchyny +" License: MIT License +" Last Change: 2015/03/29 06:28:49. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +let s:constructor = calendar#constructor#day_hybrid#new(1923, 3, 1) + +function! calendar#day#greece#new(y, m, d) abort + return s:constructor.new(a:y, a:m, a:d) +endfunction + +function! calendar#day#greece#new_mjd(mjd) abort + return s:constructor.new_mjd(a:mjd) +endfunction + +function! calendar#day#greece#today() abort + return s:constructor.today() +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/day/gregorian.vim b/bundle/calendar.vim/autoload/calendar/day/gregorian.vim new file mode 100644 index 000000000..b39b8cdff --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/day/gregorian.vim @@ -0,0 +1,75 @@ +" ============================================================================= +" Filename: autoload/calendar/day/gregorian.vim +" Author: itchyny +" License: MIT License +" Last Change: 2017/05/07 22:04:31. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +function! s:div(x, y) abort + return a:x/a:y-((a:x<0)&&(a:x%a:y)) +endfunction + +function! calendar#day#gregorian#new(y, m, d) abort + return s:constructor.new(a:y, a:m, a:d) +endfunction + +function! calendar#day#gregorian#new_mjd(mjd) abort + return s:constructor.new_mjd(a:mjd) +endfunction + +function! calendar#day#gregorian#today() abort + return s:constructor.new_mjd(calendar#day#today_mjd()) +endfunction + +let s:self = {} + +function! s:self.new(y, m, d) dict abort + let y = a:y - (a:m < 3) + let mjd = s:div(y*1461,4)+s:div(y,400)-s:div(y,100)+((a:m+12*(a:m<3)-3)*153+2)/5+a:d-678882 + return extend(self.new_mjd(mjd), { '_ymd': [a:y, a:m, a:d] }) +endfunction + +function! s:self.new_mjd(mjd) dict abort + return s:constructor.new_mjd(a:mjd) +endfunction + +let s:_ = {} +let s:days = { '1': 31, '2': 28, '3': 31, '4': 30, '5': 31, '6': 30, '7': 31, '8': 31, '9': 30, '10': 31, '11': 30, '12': 31 } +function! s:self.get_ymd() dict abort + if has_key(self, 'ymd') | return self.ymd | endif + let _ = self.mjd + if has_key(s:_, _) | return s:_[_] | endif + if has_key(s:_, _ - 1) && s:_[_ - 1][2] < s:days[s:_[_ - 1][1]] + let p = s:_[_ - 1] + let s:_[_] = [p[0], p[1], p[2] + 1] + return s:_[_] + endif + let a = _ + 2432045 + let b = s:div(4 * a + 3, 146097) + let c = a - s:div(146097 * b, 4) + let d = (4 * c + 3) / 1461 + let e = c - (1461 * d) / 4 + let m = (5 * e + 2) / 153 + let day = e - (153 * m + 2) / 5 + 1 + let month = m + 3 - 12 * (m / 10) + let year = 100 * b + d - 4800 + m / 10 + let self.ymd = [year, month, day] + let s:_[_] = self.ymd + return self.ymd +endfunction + +function! s:self.is_gregorian() dict abort + return 1 +endfunction + +function! s:self.get_calendar() dict abort + return 'gregorian' +endfunction + +let s:constructor = calendar#constructor#day#new(s:self) + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/day/holland.vim b/bundle/calendar.vim/autoload/calendar/day/holland.vim new file mode 100644 index 000000000..ddc90d4c5 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/day/holland.vim @@ -0,0 +1,26 @@ +" ============================================================================= +" Filename: autoload/calendar/day/holland.vim +" Author: itchyny +" License: MIT License +" Last Change: 2015/03/29 06:28:56. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +let s:constructor = calendar#constructor#day_hybrid#new(1583, 1, 1) + +function! calendar#day#holland#new(y, m, d) abort + return s:constructor.new(a:y, a:m, a:d) +endfunction + +function! calendar#day#holland#new_mjd(mjd) abort + return s:constructor.new_mjd(a:mjd) +endfunction + +function! calendar#day#holland#today() abort + return s:constructor.today() +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/day/hungary.vim b/bundle/calendar.vim/autoload/calendar/day/hungary.vim new file mode 100644 index 000000000..d9a11a1d8 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/day/hungary.vim @@ -0,0 +1,26 @@ +" ============================================================================= +" Filename: autoload/calendar/day/hungary.vim +" Author: itchyny +" License: MIT License +" Last Change: 2015/03/29 06:28:57. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +let s:constructor = calendar#constructor#day_hybrid#new(1587, 11, 1) + +function! calendar#day#hungary#new(y, m, d) abort + return s:constructor.new(a:y, a:m, a:d) +endfunction + +function! calendar#day#hungary#new_mjd(mjd) abort + return s:constructor.new_mjd(a:mjd) +endfunction + +function! calendar#day#hungary#today() abort + return s:constructor.today() +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/day/italy.vim b/bundle/calendar.vim/autoload/calendar/day/italy.vim new file mode 100644 index 000000000..b11546c71 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/day/italy.vim @@ -0,0 +1,26 @@ +" ============================================================================= +" Filename: autoload/calendar/day/italy.vim +" Author: itchyny +" License: MIT License +" Last Change: 2015/03/29 06:28:59. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +let s:constructor = calendar#constructor#day_hybrid#new(1582, 10, 15) + +function! calendar#day#italy#new(y, m, d) abort + return s:constructor.new(a:y, a:m, a:d) +endfunction + +function! calendar#day#italy#new_mjd(mjd) abort + return s:constructor.new_mjd(a:mjd) +endfunction + +function! calendar#day#italy#today() abort + return s:constructor.today() +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/day/japan.vim b/bundle/calendar.vim/autoload/calendar/day/japan.vim new file mode 100644 index 000000000..bf2f0aae8 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/day/japan.vim @@ -0,0 +1,30 @@ +" ============================================================================= +" Filename: autoload/calendar/day/japan.vim +" Author: itchyny +" License: MIT License +" Last Change: 2015/03/29 06:29:01. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +" TODO: In Japan, The calendar before switching to Gregorian's calendar was +" not Julian's. It was a lunisolar calendar. Therefore, the day before 1873/1/1 +" was 1872/12/3, not 1872/12/19. For more infomation, see: +" http://en.wikipedia.org/wiki/Tenp%C5%8D_calendar +let s:constructor = calendar#constructor#day_hybrid#new(1873, 1, 1) + +function! calendar#day#japan#new(y, m, d) abort + return s:constructor.new(a:y, a:m, a:d) +endfunction + +function! calendar#day#japan#new_mjd(mjd) abort + return s:constructor.new_mjd(a:mjd) +endfunction + +function! calendar#day#japan#today() abort + return s:constructor.today() +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/day/julian.vim b/bundle/calendar.vim/autoload/calendar/day/julian.vim new file mode 100644 index 000000000..7172793a0 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/day/julian.vim @@ -0,0 +1,66 @@ +" ============================================================================= +" Filename: autoload/calendar/day/julian.vim +" Author: itchyny +" License: MIT License +" Last Change: 2017/05/07 22:12:02. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +function! s:div(x, y) abort + return a:x/a:y-((a:x<0)&&(a:x%a:y)) +endfunction + +function! calendar#day#julian#new(y, m, d) abort + return s:constructor.new(a:y, a:m, a:d) +endfunction + +function! calendar#day#julian#new_mjd(mjd) abort + return s:constructor.new_mjd(a:mjd) +endfunction + +function! calendar#day#julian#today() abort + return s:constructor.new_mjd(calendar#day#today_mjd()) +endfunction + +let s:self = {} + +function! s:self.new(y, m, d) dict abort + let y = a:y - (a:m < 3) + let mjd = s:div(y*1461,4)+((a:m+12*(a:m<3)-3)*153+2)/5+a:d-678884 + return extend(self.new_mjd(mjd), { '_ymd': [a:y, a:m, a:d] }) +endfunction + +function! s:self.new_mjd(mjd) dict abort + return s:constructor.new_mjd(a:mjd) +endfunction + +let s:_ = {} +function! s:self.get_ymd() dict abort + if has_key(self, 'ymd') | return self.ymd | endif + if has_key(s:_, self.mjd) | return s:_[self.mjd] | endif + let c = self.mjd + 678883 + let d = s:div(4 * c + 3, 1461) + let e = c - s:div(1461 * d, 4) + let m = (5 * e + 2) / 153 + let day = e - (153 * m + 2) / 5 + 1 + let month = m + 3 - 12 * (m / 10) + let year = d + m / 10 + let self.ymd = [year, month, day] + let s:_[self.mjd] = self.ymd + return self.ymd +endfunction + +function! s:self.is_gregorian() dict abort + return 0 +endfunction + +function! s:self.get_calendar() dict abort + return 'julian' +endfunction + +let s:constructor = calendar#constructor#day#new(s:self) + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/day/poland.vim b/bundle/calendar.vim/autoload/calendar/day/poland.vim new file mode 100644 index 000000000..92ea9a4de --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/day/poland.vim @@ -0,0 +1,26 @@ +" ============================================================================= +" Filename: autoload/calendar/day/poland.vim +" Author: itchyny +" License: MIT License +" Last Change: 2015/03/29 06:29:08. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +let s:constructor = calendar#constructor#day_hybrid#new(1582, 10, 15) + +function! calendar#day#poland#new(y, m, d) abort + return s:constructor.new(a:y, a:m, a:d) +endfunction + +function! calendar#day#poland#new_mjd(mjd) abort + return s:constructor.new_mjd(a:mjd) +endfunction + +function! calendar#day#poland#today() abort + return s:constructor.today() +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/day/portugal.vim b/bundle/calendar.vim/autoload/calendar/day/portugal.vim new file mode 100644 index 000000000..f86ab274f --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/day/portugal.vim @@ -0,0 +1,26 @@ +" ============================================================================= +" Filename: autoload/calendar/day/portugal.vim +" Author: itchyny +" License: MIT License +" Last Change: 2015/03/29 06:29:09. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +let s:constructor = calendar#constructor#day_hybrid#new(1582, 10, 15) + +function! calendar#day#portugal#new(y, m, d) abort + return s:constructor.new(a:y, a:m, a:d) +endfunction + +function! calendar#day#portugal#new_mjd(mjd) abort + return s:constructor.new_mjd(a:mjd) +endfunction + +function! calendar#day#portugal#today() abort + return s:constructor.today() +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/day/russia.vim b/bundle/calendar.vim/autoload/calendar/day/russia.vim new file mode 100644 index 000000000..f51e7dc73 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/day/russia.vim @@ -0,0 +1,26 @@ +" ============================================================================= +" Filename: autoload/calendar/day/russia.vim +" Author: itchyny +" License: MIT License +" Last Change: 2015/03/29 06:29:11. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +let s:constructor = calendar#constructor#day_hybrid#new(1918, 2, 14) + +function! calendar#day#russia#new(y, m, d) abort + return s:constructor.new(a:y, a:m, a:d) +endfunction + +function! calendar#day#russia#new_mjd(mjd) abort + return s:constructor.new_mjd(a:mjd) +endfunction + +function! calendar#day#russia#today() abort + return s:constructor.today() +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/day/spain.vim b/bundle/calendar.vim/autoload/calendar/day/spain.vim new file mode 100644 index 000000000..f533b7684 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/day/spain.vim @@ -0,0 +1,26 @@ +" ============================================================================= +" Filename: autoload/calendar/day/spain.vim +" Author: itchyny +" License: MIT License +" Last Change: 2015/03/29 06:29:12. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +let s:constructor = calendar#constructor#day_hybrid#new(1582, 10, 15) + +function! calendar#day#spain#new(y, m, d) abort + return s:constructor.new(a:y, a:m, a:d) +endfunction + +function! calendar#day#spain#new_mjd(mjd) abort + return s:constructor.new_mjd(a:mjd) +endfunction + +function! calendar#day#spain#today() abort + return s:constructor.today() +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/day/turkey.vim b/bundle/calendar.vim/autoload/calendar/day/turkey.vim new file mode 100644 index 000000000..e3b656cc8 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/day/turkey.vim @@ -0,0 +1,26 @@ +" ============================================================================= +" Filename: autoload/calendar/day/turkey.vim +" Author: itchyny +" License: MIT License +" Last Change: 2015/03/29 06:29:14. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +let s:constructor = calendar#constructor#day_hybrid#new(1927, 1, 1) + +function! calendar#day#turkey#new(y, m, d) abort + return s:constructor.new(a:y, a:m, a:d) +endfunction + +function! calendar#day#turkey#new_mjd(mjd) abort + return s:constructor.new_mjd(a:mjd) +endfunction + +function! calendar#day#turkey#today() abort + return s:constructor.today() +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/day/us.vim b/bundle/calendar.vim/autoload/calendar/day/us.vim new file mode 100644 index 000000000..18f70bd6f --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/day/us.vim @@ -0,0 +1,26 @@ +" ============================================================================= +" Filename: autoload/calendar/day/us.vim +" Author: itchyny +" License: MIT License +" Last Change: 2015/03/29 06:29:16. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +let s:constructor = calendar#constructor#day_hybrid#new(1752, 9, 14) + +function! calendar#day#us#new(y, m, d) abort + return s:constructor.new(a:y, a:m, a:d) +endfunction + +function! calendar#day#us#new_mjd(mjd) abort + return s:constructor.new_mjd(a:mjd) +endfunction + +function! calendar#day#us#today() abort + return s:constructor.today() +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/echo.vim b/bundle/calendar.vim/autoload/calendar/echo.vim new file mode 100644 index 000000000..c9903a1d3 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/echo.vim @@ -0,0 +1,52 @@ +" ============================================================================= +" Filename: autoload/calendar/echo.vim +" Author: itchyny +" License: MIT License +" Last Change: 2015/03/29 06:29:23. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +" Echo messages. + +function! calendar#echo#echo(msg) abort + echo a:msg +endfunction + +function! calendar#echo#message(msg) abort + call calendar#echo#message_raw(calendar#setting#get('message_prefix') . a:msg) +endfunction + +function! calendar#echo#message_raw(msg) abort + redraw + echo '' + for msg in split(a:msg, '\n') + echo msg + endfor +endfunction + +function! calendar#echo#error(msg) abort + call calendar#echo#error_raw(calendar#setting#get('message_prefix') . a:msg) +endfunction + +function! calendar#echo#error_raw(msg) abort + redraw + echo '' + echohl ErrorMsg + for msg in split(a:msg, '\n') + echo msg + endfor + echohl None +endfunction + +function! calendar#echo#normal_message(name) abort + call calendar#echo#message(calendar#message#get(a:name)) +endfunction + +function! calendar#echo#error_message(name) abort + call calendar#echo#error(calendar#message#get(a:name)) +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/event.vim b/bundle/calendar.vim/autoload/calendar/event.vim new file mode 100644 index 000000000..f973657d8 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/event.vim @@ -0,0 +1,136 @@ +" ============================================================================= +" Filename: autoload/calendar/event.vim +" Author: itchyny +" License: MIT License +" Last Change: 2020/10/17 01:37:16. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +" Event controller. +" This object handles both local and Google Calendar. +function! calendar#event#new() abort + let self = deepcopy(s:self) + if calendar#setting#get('google_calendar') + let self.event_source_name = 'google' + else + let self.event_source_name = 'local' + endif + let self.event_source = calendar#event#{self.event_source_name}#new() + return self +endfunction + +let s:self = {} + +let s:self.__events = {} +let s:self._holidays = {} +let s:self._updated = 0 + +function! s:self.updated() dict abort + if self._updated > 0 + let self._updated -= 1 + endif + return [self._updated] +endfunction + +function! s:self.get_events_one_month(year, month, ...) dict abort + let events = self.event_source.get_events_one_month(a:year, a:month, a:0 && a:1) + if self.event_source_name !=# 'google' + let holiday = self.get_holidays(a:year, a:month) + for day in keys(holiday) + if len(holiday[day].events) + if !has_key(events, day) + let events[day] = { 'events': [] } + endif + let events[day].hasHoliday = 1 + call extend(events[day].events, holiday[day].events) + let events[day].holiday = holiday[day].events[-1].summary + endif + endfor + endif + return events +endfunction + +function! s:self.clear_cache() dict abort + let self.__events = {} + let self._holidays = {} + let self._updated = 10 + call self.event_source.clear_cache() +endfunction + +function! s:self.get_events(year, month) dict abort + let key = a:year . '-' . a:month + if self._updated > 0 + let self._updated -= 1 + endif + if has_key(self.__events, key) && (!calendar#setting#get('google_calendar') || get(g:, 'calendar_google_event_download', 1) <= 0) && !self._updated + return self.__events[key] + endif + let events = self.get_events_one_month(a:year, a:month, 1) + let [year, month] = calendar#day#new(a:year, a:month, 1).month().add(1).get_ym() + call extend(events, self.get_events_one_month(year, month, 0)) + let [year, month] = calendar#day#new(a:year, a:month, 1).month().add(-1).get_ym() + call extend(events, self.get_events_one_month(year, month, 0)) + let self.__events[key] = events + return self.__events[key] +endfunction + +function! s:self.get_holidays(year, month) dict abort + let key = a:year . '-' . a:month + if has_key(self._holidays, key) && (!calendar#setting#get('google_calendar') || get(g:, 'calendar_google_event_download', 1) <= 0) + return self._holidays[key] + endif + let self._holidays[key] = calendar#google#calendar#getHolidays(a:year, a:month) + return self._holidays[key] +endfunction + +function! s:self.update(calendarId, eventId, title, year, month, ...) dict abort + let self._updated = 10 + return self.event_source.update(a:calendarId, a:eventId, a:title, a:year, a:month, a:0 ? a:1 : {}) +endfunction + +function! s:self.insert(calendarId, title, start, end, year, month, ...) dict abort + let self._updated = 10 + return self.event_source.insert(a:calendarId, a:title, a:start, a:end, a:year, a:month, a:0 ? a:1 : {}) +endfunction + +function! s:self.move(calendarId, eventId, destination, year, month) dict abort + let self._updated = 10 + return self.event_source.move(a:calendarId, a:eventId, a:destination, a:year, a:month) +endfunction + +function! s:self.delete(calendarId, eventId, year, month) dict abort + let self._updated = 10 + return self.event_source.delete(a:calendarId, a:eventId, a:year, a:month) +endfunction + +function! s:self.createCalendar() dict abort + let self._updated = 10 + return self.event_source.createCalendar() +endfunction + +function! s:self.calendarList() dict abort + return self.event_source.calendarList() +endfunction + +function! s:self.calendarCandidates() dict abort + let calendars = self.event_source.calendarList() + let calendar_candidates = calendar#setting#get('calendar_candidates') + if type(calendar_candidates) ==# type('') || type(calendar_candidates) ==# type([]) + let cs = [] + for pattern in type(calendar_candidates) ==# type('') ? + \ split(calendar_candidates, ', *') : calendar_candidates + for c in calendars + if c.summary =~# pattern + call add(cs, c) + endif + endfor + endfor + let calendars = cs + endif + return calendars +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/event/google.vim b/bundle/calendar.vim/autoload/calendar/event/google.vim new file mode 100644 index 000000000..1eb62db88 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/event/google.vim @@ -0,0 +1,68 @@ +" ============================================================================= +" Filename: autoload/calendar/event/google.vim +" Author: itchyny +" License: MIT License +" Last Change: 2017/05/23 22:01:14. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +function! calendar#event#google#new() abort + return deepcopy(s:self) +endfunction + +let s:self = {} +let s:self._key = {} +let s:self._events = {} + +function! s:self.get_events_one_month(year, month, ...) dict abort + let key = a:year . '-' . a:month + if has_key(self._key, key) && has_key(self._events, key) && get(g:, 'calendar_google_event_download', 1) <= 0 && self._events[key] != {} + if a:0 && a:1 + call calendar#google#calendar#getEventsInitial(a:year, a:month) + endif + return self._events[key] + endif + if has_key(self._key, key) + unlet self._key[key] + endif + if has_key(g:, 'calendar_google_event_download') + if get(g:, 'calendar_google_event_download') > 1 + let g:calendar_google_event_download -= 1 + endif + endif + let self._events[key] = calendar#google#calendar#getEvents(a:year, a:month, a:0 && a:1) + let self._key[key] = 1 + return self._events[key] +endfunction + +function! s:self.update(calendarId, eventId, title, year, month, ...) dict abort + call calendar#google#calendar#update(a:calendarId, a:eventId, a:title, a:year, a:month, a:0 ? a:1 : {}) +endfunction + +function! s:self.insert(calendarId, title, start, end, year, month, ...) dict abort + call calendar#google#calendar#insert(a:calendarId, a:title, a:start, a:end, a:year, a:month, a:0 ? a:1 : {}) +endfunction + +function! s:self.move(calendarId, eventId, destination, year, month) dict abort + call calendar#google#calendar#move(a:calendarId, a:eventId, a:destination, a:year, a:month) +endfunction + +function! s:self.delete(calendarId, eventId, year, month) dict abort + call calendar#google#calendar#delete(a:calendarId, a:eventId, a:year, a:month) +endfunction + +function! s:self.calendarList() dict abort + return calendar#google#calendar#getMyCalendarList() +endfunction + +function! s:self.createCalendar() dict abort +endfunction + +function! s:self.clear_cache() dict abort + call calendar#google#calendar#clearCache() +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/event/local.vim b/bundle/calendar.vim/autoload/calendar/event/local.vim new file mode 100644 index 000000000..2e3898f0e --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/event/local.vim @@ -0,0 +1,250 @@ +" ============================================================================= +" Filename: autoload/calendar/event/local.vim +" Author: itchyny +" License: MIT License +" Last Change: 2021/01/30 16:44:33. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +function! calendar#event#local#new() abort + return deepcopy(s:self) +endfunction + +let s:cache = calendar#cache#new('local') + +let s:event_cache = s:cache.new('event') + +let s:self = {} +let s:self._key = {} +let s:self._events = {} + +function! s:self.get_events_one_month(year, month, ...) dict abort + let events = {} + let calendarList = self.calendarList() + let [y, m] = [printf('%04d', a:year), printf('%02d', a:month)] + let clock_12hour = calendar#setting#get('clock_12hour') + for calendar in calendarList + let syn = calendar#color#new_syntax(get(calendar, 'id', ''), get(calendar, 'foregroundColor', ''), get(calendar, 'backgroundColor')) + unlet! c + let c = s:event_cache.new(calendar.id).new(y).new(m).get('0') + if type(c) != type({}) || type(get(c, 'items')) != type([]) + continue + endif + for itm in c.items + if !(has_key(itm, 'start') && (has_key(itm.start, 'date') || has_key(itm.start, 'dateTime')) + \ && has_key(itm, 'end') && (has_key(itm.end, 'date') || has_key(itm.end, 'dateTime'))) + continue + endif + let isTimeEvent = (!has_key(itm.start, 'date')) && has_key(itm.start, 'dateTime') && (!has_key(itm.end, 'date')) && has_key(itm.end, 'dateTime') + let ymd = calendar#time#datetime(get(itm.start, 'date', get(itm.start, 'dateTime', ''))) + let endymd = calendar#time#datetime(get(itm.end, 'date', get(itm.end, 'dateTime', ''))) + if len(ymd) != 6 || len(endymd) != 6 + continue + endif + let date = join(ymd[:2], '-') + if has_key(itm.end, 'date') + let endymd = ymd[:2] == [endymd[0], endymd[1], endymd[2] - 1] ? ymd : calendar#day#new(endymd[0], endymd[1], endymd[2]).add(-1).get_ymd() + endymd[3:] + endif + if clock_12hour + let start_postfix = ymd[3] < 12 || ymd[3] == 24 ? 'am' : 'pm' + let end_postfix = endymd[3] < 12 || endymd[3] == 24 ? 'am' : 'pm' + let starttime = ymd[5] ? + \ printf('%d:%02d:%02d%s', calendar#time#hour12(ymd[3]), ymd[4], ymd[5], start_postfix ==# end_postfix ? '' : start_postfix) : + \ printf('%d:%02d%s', calendar#time#hour12(ymd[3]), ymd[4], start_postfix ==# end_postfix ? '' : start_postfix) + let endtime = endymd[5] ? + \ printf('%d:%02d:%02d%s', calendar#time#hour12(endymd[3]), endymd[4], endymd[5], end_postfix) : + \ printf('%d:%02d%s', calendar#time#hour12(endymd[3]), endymd[4], end_postfix) + else + let starttime = ymd[5] ? printf('%d:%02d:%02d', ymd[3], ymd[4], ymd[5]) : printf('%d:%02d', ymd[3], ymd[4]) + let endtime = endymd[5] ? printf('%d:%02d:%02d', endymd[3], endymd[4], endymd[5]) : printf('%d:%02d', endymd[3], endymd[4]) + endif + if !has_key(events, date) + let events[date] = { 'events': [] } + endif + call add(events[date].events, extend(itm, + \ { 'calendarId': calendar.id + \ , 'calendarSummary': calendar.summary + \ , 'syntax': syn + \ , 'isTimeEvent': isTimeEvent + \ , 'isHoliday': 0 + \ , 'isMoon': 0 + \ , 'isDayNum': 0 + \ , 'isWeekNum': 0 + \ , 'starttime': starttime + \ , 'endtime': endtime + \ , 'ymdnum': (((ymd[0] * 100 + ymd[1]) * 100) + ymd[2]) + \ , 'hms': ymd[3:] + \ , 'sec': isTimeEvent ? ((ymd[3] * 60) + ymd[4]) * 60 + ymd[5] + \ : get(itm, 'summary', '') =~# '\v^\d\d?:\d\d(:\d\d)?\s+' ? s:extract_time_sec(itm.summary) : 0 + \ , 'ymd': ymd[:2] + \ , 'endhms': endymd[3:] + \ , 'endymd': endymd[:2] })) + endfor + endfor + for date in keys(events) + call sort(events[date].events, function('s:events_sorter')) + endfor + return events +endfunction + +function! s:extract_time_sec(summary) abort + let xs = matchlist(a:summary, '\v^(\d\d?):(\d\d)%(:(\d\d))?') + return ((xs[1] * 60) + xs[2]) * 60 + xs[3] +endfunction + +function! s:events_sorter(x, y) abort + return a:x.calendarId ==# a:y.calendarId + \ ? (a:x.sec == a:y.sec + \ ? (get(a:x, 'summary', '') > get(a:y, 'summary', '') ? 1 : -1) + \ : a:x.sec > a:y.sec ? 1 : -1) : 0 +endfunction + +function! s:self.update(calendarId, eventId, title, year, month, ...) dict abort + let calendarList = self.calendarList() + let [y, m] = [printf('%04d', a:year), printf('%02d', a:month)] + for calendar in calendarList + if calendar.id ==# a:calendarId + let c = s:event_cache.new(calendar.id).new(y).new(m).get('0') + let cnt = type(c) == type({}) && has_key(c, 'items') && type(c.items) == type([]) ? c : { 'items': [] } + for i in range(len(cnt.items)) + if cnt.items[i].id ==# a:eventId + let cnt.items[i].summary = a:title + call extend(cnt.items[i], a:0 ? a:1 : {}) + call s:event_cache.new(calendar.id).new(y).new(m).save('0', cnt) + return + endif + endfor + endif + endfor +endfunction + +function! s:self.insert(calendarId, title, start, end, year, month, ...) dict abort + let calendarList = self.calendarList() + let [y, m] = [printf('%04d', a:year), printf('%02d', a:month)] + if a:start =~# '\v^\d+[-/]\d+[-/]\d+' + let ymd = map(split(matchstr(a:start, '\v^\d+[-/]\d+[-/]\d+'), '[-/]'), 'v:val + 0') + let [y, m] = [printf('%04d', ymd[0]), printf('%02d', ymd[1])] + elseif a:start =~# '\v^\d+[-/]\d+' + let md = map(split(matchstr(a:start, '\v^\d+[-/]\d+'), '[-/]'), 'v:val + 0') + let m = printf('%04d', md[0]) + endif + for calendar in calendarList + if calendar.id ==# a:calendarId + let c = s:event_cache.new(calendar.id).new(y).new(m).get('0') + let cnt = type(c) == type({}) && has_key(c, 'items') && type(c.items) == type([]) ? c : { 'items': [] } + call add(cnt.items, + \ { 'id': calendar#util#id() + \ , 'summary': a:title + \ , 'start': a:start =~# '\vT\d+' ? { 'dateTime': a:start } : { 'date': a:start } + \ , 'end': a:end =~# '\vT\d+' ? { 'dateTime': a:end } : { 'date': a:end } + \ }) + call s:event_cache.new(calendar.id).new(y).new(m).save('0', cnt) + return + endif + endfor +endfunction + +function! s:self.move(calendarId, eventId, destination, year, month) dict abort + let calendarList = self.calendarList() + let [y, m] = [printf('%04d', a:year), printf('%02d', a:month)] + let event = {} + for calendar in calendarList + if calendar.id ==# a:calendarId + let c = s:event_cache.new(calendar.id).new(y).new(m).get('0') + let cnt = type(c) == type({}) && has_key(c, 'items') && type(c.items) == type([]) ? c : { 'items': [] } + for i in range(len(cnt.items)) + if cnt.items[i].id ==# a:eventId + let event = deepcopy(cnt.items[i]) + call remove(cnt.items, i) + call s:event_cache.new(calendar.id).new(y).new(m).save('0', cnt) + break + endif + endfor + endif + endfor + for calendar in calendarList + if calendar.id ==# a:destination + let c = s:event_cache.new(calendar.id).new(y).new(m).get('0') + let cnt = type(c) == type({}) && has_key(c, 'items') && type(c.items) == type([]) ? c : { 'items': [] } + call add(cnt.items, + \ { 'id': calendar#util#id() + \ , 'summary': event.summary + \ , 'start': event.start + \ , 'end': event.end + \ }) + call s:event_cache.new(calendar.id).new(y).new(m).save('0', cnt) + return + endif + endfor +endfunction + +function! s:self.delete(calendarId, eventId, year, month) dict abort + let calendarList = self.calendarList() + let [y, m] = [printf('%04d', a:year), printf('%02d', a:month)] + for calendar in calendarList + if calendar.id ==# a:calendarId + let c = s:event_cache.new(calendar.id).new(y).new(m).get('0') + let cnt = type(c) == type({}) && has_key(c, 'items') && type(c.items) == type([]) ? c : { 'items': [] } + for i in range(len(cnt.items)) + if cnt.items[i].id ==# a:eventId + call remove(cnt.items, i) + call s:event_cache.new(calendar.id).new(y).new(m).save('0', cnt) + return + endif + endfor + endif + endfor +endfunction + +function! s:self.calendarList() dict abort + if has_key(self, '_calendarList') + return self._calendarList + endif + let self._calendarList = [] + let cnt = s:cache.get('calendarList') + if type(cnt) == type({}) && has_key(cnt, 'items') && type(cnt.items) == type([]) + let self._calendarList = filter(cnt.items, 'has_key(v:val, "id") && has_key(v:val, "summary")') + endif + return self._calendarList +endfunction + +function! s:self.createCalendar() dict abort + let cnt = s:cache.get('calendarList') + if type(cnt) == type({}) && has_key(cnt, 'items') && type(cnt.items) == type([]) + let c = cnt + else + let c = { 'items': [] } + endif + redraw + let calendarTitle = input(calendar#message#get('input_calendar_name')) + if len(calendarTitle) + let colors = [] + for itm in c.items + if has_key(itm, 'backgroundColor') + call add(colors, itm.backgroundColor) + endif + endfor + let newcolors = filter(calendar#color#colors(), 'index(colors, v:val) >= 0') + if len(newcolors) == 0 + let newcolors = calendar#color#colors() + endif + call add(c.items, + \ { 'id': calendar#util#id() + \ , 'summary': calendarTitle + \ , 'backgroundColor': newcolors[0] + \ , 'foregroundColor': '#000000' + \ }) + call s:cache.save('calendarList', c) + if has_key(self, '_calendarList') + unlet! self._calendarList + endif + endif +endfunction + +function! s:self.clear_cache() dict abort +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/google/calendar.vim b/bundle/calendar.vim/autoload/calendar/google/calendar.vim new file mode 100644 index 000000000..55813c642 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/google/calendar.vim @@ -0,0 +1,618 @@ +" ============================================================================= +" Filename: autoload/calendar/google/calendar.vim +" Author: itchyny +" License: MIT License +" Last Change: 2020/11/19 07:40:32. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +let s:cache = calendar#cache#new('google') + +let s:event_cache = s:cache.new('event') + +let g:calendar_google_event_download = 0 +let g:calendar_google_event_downloading = {} +let g:calendar_google_event_downloading_list = 0 + +function! calendar#google#calendar#get_url(type) abort + return 'https://www.googleapis.com/calendar/v3/' . a:type +endfunction + +function! calendar#google#calendar#getCalendarList() abort + let calendarList = s:cache.get('calendarList') + if (!g:calendar_google_event_downloading_list) && (type(calendarList) != type({}) || + \ calendar#timestamp#update('google_calendarlist', 24 * 60 * 60)) + let g:calendar_google_event_downloading_list = 1 + call calendar#google#client#get_async(s:newid(['calendarList', 0]), + \ 'calendar#google#calendar#getCalendarList_response', + \ calendar#google#calendar#get_url('users/me/calendarList')) + endif + return type(calendarList) == type({}) ? calendarList : {} +endfunction + +function! calendar#google#calendar#getCalendarList_response(id, response) abort + let [_calendarlist, err; rest] = s:getdata(a:id) + if a:response.status =~# '^2' + let cnt = calendar#webapi#decode(a:response.content) + let content = type(cnt) == type({}) ? cnt : {} + if has_key(content, 'items') && type(content.items) == type([]) + let content.items = filter(deepcopy(content.items), 'get(v:val, "accessRole", "") ==# "owner"') + \ + filter(deepcopy(content.items), 'get(v:val, "accessRole", "") !=# "owner"') + call s:cache.save('calendarList', content) + let g:calendar_google_event_downloading_list = 0 + let g:calendar_google_event_download = 3 + silent! let b:calendar.event._updated = 3 + silent! call b:calendar.update() + endif + elseif a:response.status == 401 + if err == 0 + call calendar#google#client#refresh_token() + call calendar#google#client#get_async(s:newid(['calendarList', err + 1]), + \ 'calendar#google#calendar#getCalendarList_response', + \ calendar#google#calendar#get_url('users/me/calendarList')) + endif + endif +endfunction + +function! calendar#google#calendar#getMyCalendarList() abort + let calendarList = calendar#google#calendar#getCalendarList() + let validCalendar = filter(get(deepcopy(calendarList), 'items', []), 'type(v:val) == type({}) && has_key(v:val, "summary") && has_key(v:val, "id")') + return filter(validCalendar, 'get(v:val, "selected") && (get(v:val, "accessRole", "") ==# "owner" || (get(v:val, "summary", "") !=# "Phases of the Moon") && get(v:val, "id", "") !~# "holiday@")') +endfunction + +function! calendar#google#calendar#getColors() abort + let colors = s:cache.get('colors') + if calendar#timestamp#update('google_calendarcolor', 7 * 24 * 60 * 60) + call calendar#google#client#get_async(s:newid(['calendarColor', 0]), + \ 'calendar#google#calendar#getColors_response', + \ calendar#google#calendar#get_url('colors')) + endif + return type(colors) == type({}) ? colors : {} +endfunction + +function! calendar#google#calendar#getColors_response(id, response) abort + let [_calendarlist, err; rest] = s:getdata(a:id) + let colors = s:cache.get('colors') + if a:response.status =~# '^2' + let cnt = calendar#webapi#decode(a:response.content) + let content = type(cnt) == type({}) ? cnt : {} + if has_key(content, 'event') && type(content.event) == type({}) + call s:cache.save('colors', content) + silent! call b:calendar.update() + endif + endif +endfunction + +function! calendar#google#calendar#getEventSummary(year, month) abort + let calendarList = calendar#google#calendar#getCalendarList() + let events = [] + if has_key(calendarList, 'items') && type(calendarList.items) == type([]) && len(calendarList.items) + let [y, m] = [printf('%04d', a:year), printf('%02d', a:month)] + for item in calendarList.items + unlet! cnt + if get(item, 'selected') + let cnt = s:event_cache.new(item.id).new(y).new(m).get('information') + if type(cnt) == type({}) && has_key(cnt, 'summary') + call add(events, cnt) + else + call calendar#google#calendar#downloadEvents(a:year, a:month) + break + endif + endif + endfor + endif + return events +endfunction + +function! calendar#google#calendar#initialDownload(year, month, index) abort + let myCalendarList = calendar#google#calendar#getMyCalendarList() + let key = join([a:year, a:month], '/') + if a:index < len(myCalendarList) && get(s:initial_download, key, 2) < 2 + call calendar#async#new(printf('calendar#google#calendar#downloadEvents(%d, %d, "%s", %d)', a:year, a:month, myCalendarList[a:index].id, a:index)) + endif +endfunction + +let s:initial_download = {} +let s:event_download = {} +function! calendar#google#calendar#getEventsInitial(year, month) abort + let myCalendarList = calendar#google#calendar#getMyCalendarList() + let events = {} + let key = join([a:year, a:month], '/') + if !get(s:initial_download, key) + let s:initial_download[key] = 1 + if len(myCalendarList) && calendar#timestamp#update(printf('google_calendar_%04d%02d', a:year, a:month), 30 * 60) + call calendar#async#new(printf('calendar#google#calendar#initialDownload(%d, %d, 0)', a:year, a:month)) + endif + endif +endfunction + +function! calendar#google#calendar#clearCache() abort + let s:initial_download = {} + let s:event_download = {} + unlet! g:calendar_google_event_download + call calendar#timestamp#clear() +endfunction + +" The optional argument: Forcing initial download. s:initial_download is used to check. +function! calendar#google#calendar#getEvents(year, month, ...) abort + let s:is_dark = calendar#color#is_dark() + let calendarList = calendar#google#calendar#getCalendarList() + let colors = get(calendar#google#calendar#getColors(), 'event', {}) + let events = {} + let key = join([a:year, a:month], '/') + if a:0 && a:1 + call calendar#google#calendar#getEventsInitial(a:year, a:month) + endif + if type(get(calendarList, 'items')) != type([]) + return events + endif + let [y, m] = [printf('%04d', a:year), printf('%02d', a:month)] + let clock_12hour = calendar#setting#get('clock_12hour') + for item in calendarList.items + if !get(item, 'selected') + continue + endif + let isHoliday = item.id =~# 'holiday@group.v.calendar.google.com' + let isMoon = item.summary ==# 'Phases of the Moon' && &enc ==# 'utf-8' && &fenc ==# 'utf-8' + let isDayNum = item.summary ==# 'Day of the Year' + let isWeekNum = item.summary ==# 'Week Numbers' + let calendarsyn = calendar#color#new_syntax(get(item, 'id', ''), get(item, 'foregroundColor', ''), get(item, 'backgroundColor', '')) + unlet! cnt + let cnt = s:event_cache.new(item.id).new(y).new(m).get('information') + if type(cnt) == type({}) && has_key(cnt, 'summary') + let index = 0 + while 1 + unlet! c + let c = s:event_cache.new(item.id).new(y).new(m).get(index) + if type(c) != type({}) + break + endif + let index += 1 + if type(get(c, 'items')) != type([]) + continue + endif + for itm in c.items + if !(has_key(itm, 'start') && (has_key(itm.start, 'date') || has_key(itm.start, 'dateTime')) + \ && has_key(itm, 'end') && (has_key(itm.end, 'date') || has_key(itm.end, 'dateTime'))) + continue + endif + if has_key(itm, 'colorId') + let foregroundColor = get(get(colors, itm.colorId, {}), 'foreground', get(item, 'foregroundColor', '')) + let backgroundColor = get(get(colors, itm.colorId, {}), 'background', get(item, 'backgroundColor', '')) + let syn = calendar#color#new_syntax(get(itm, 'id', ''), foregroundColor, backgroundColor) + else + let syn = calendarsyn + endif + let ymd = calendar#time#datetime(get(itm.start, 'date', get(itm.start, 'dateTime', ''))) + let endymd = calendar#time#datetime(get(itm.end, 'date', get(itm.end, 'dateTime', ''))) + let isTimeEvent = (!has_key(itm.start, 'date')) && has_key(itm.start, 'dateTime') && (!has_key(itm.end, 'date')) && has_key(itm.end, 'dateTime') + if len(ymd) != 6 || len(endymd) != 6 || [a:year, a:month] != [ymd[0], ymd[1]] + continue + endif + let date = join(ymd[:2], '-') + if has_key(itm.end, 'date') + let endymd = ymd[:2] == [endymd[0], endymd[1], endymd[2] - 1] ? ymd : calendar#day#new(endymd[0], endymd[1], endymd[2]).add(-1).get_ymd() + endymd[3:] + endif + if clock_12hour + let start_postfix = ymd[3] < 12 || ymd[3] == 24 ? 'am' : 'pm' + let end_postfix = endymd[3] < 12 || endymd[3] == 24 ? 'am' : 'pm' + let starttime = ymd[5] ? + \ printf('%d:%02d:%02d%s', calendar#time#hour12(ymd[3]), ymd[4], ymd[5], start_postfix ==# end_postfix ? '' : start_postfix) : + \ printf('%d:%02d%s', calendar#time#hour12(ymd[3]), ymd[4], start_postfix ==# end_postfix ? '' : start_postfix) + let endtime = endymd[5] ? + \ printf('%d:%02d:%02d%s', calendar#time#hour12(endymd[3]), endymd[4], endymd[5], end_postfix) : + \ printf('%d:%02d%s', calendar#time#hour12(endymd[3]), endymd[4], end_postfix) + else + let starttime = ymd[5] ? printf('%d:%02d:%02d', ymd[3], ymd[4], ymd[5]) : printf('%d:%02d', ymd[3], ymd[4]) + let endtime = endymd[5] ? printf('%d:%02d:%02d', endymd[3], endymd[4], endymd[5]) : printf('%d:%02d', endymd[3], endymd[4]) + endif + if !has_key(events, date) + let events[date] = { 'events': [] } + endif + call add(events[date].events, + \ extend(itm, + \ { 'calendarId': item.id + \ , 'calendarSummary': item.summary + \ , 'syntax': syn + \ , 'isTimeEvent': isTimeEvent + \ , 'isHoliday': isHoliday + \ , 'isMoon': isMoon + \ , 'isDayNum': isDayNum + \ , 'isWeekNum': isWeekNum + \ , 'starttime': starttime + \ , 'endtime': endtime + \ , 'ymdnum': (((ymd[0] * 100 + ymd[1]) * 100) + ymd[2]) + \ , 'hms': ymd[3:] + \ , 'sec': isTimeEvent ? ((ymd[3] * 60) + ymd[4]) * 60 + ymd[5] + \ : get(itm, 'summary', '') =~# '\v^\d\d?:\d\d(:\d\d)?\s+' ? s:extract_time_sec(itm.summary) : 0 + \ , 'ymd': ymd[:2] + \ , 'endhms': endymd[3:] + \ , 'endymd': endymd[:2] })) + if isHoliday + let events[date].holiday = events[date].events[-1].summary + let events[date].hasHoliday = 1 + endif + if isMoon + call s:moon_event(events[date]) + endif + if isDayNum + let events[date].daynum = matchstr(events[date].events[-1].summary, '\d\+') + endif + if isWeekNum + let events[date].weeknum = matchstr(events[date].events[-1].summary, '\d\+') + endif + endfor + endwhile + elseif !get(s:event_download, key) + let s:event_download[key] = 1 + call calendar#google#calendar#downloadEvents(a:year, a:month) + break + endif + endfor + for date in keys(events) + call sort(events[date].events, function('calendar#google#calendar#sorter')) + endfor + return events +endfunction + +function! s:extract_time_sec(summary) abort + let xs = matchlist(a:summary, '\v^(\d\d?):(\d\d)%(:(\d\d))?') + return ((xs[1] * 60) + xs[2]) * 60 + xs[3] +endfunction + +function! calendar#google#calendar#sorter(x, y) abort + return a:x.calendarId ==# a:y.calendarId + \ ? (a:x.sec == a:y.sec + \ ? (get(a:x, 'summary', '') > get(a:y, 'summary', '') ? 1 : -1) + \ : a:x.sec > a:y.sec ? 1 : -1) : 0 +endfunction + +function! s:moon_event(events) abort + let s = a:events.events[-1].summary + let m = s =~# '^New moon' ? (s:is_dark ? "\u25cb" : "\u25cf") + \ : s =~# '^First quarter' ? (s:is_dark ? "\u25d1" : "\u25d0") + \ : s =~# '^Full moon' ? (s:is_dark ? "\u25cf" : "\u25cb") + \ : s =~# '^Last quarter' ? (s:is_dark ? "\u25d0" : "\u25d1") + \ : '' + let a:events.moon = calendar#string#truncate(m, 2) + if m !=# '' + let a:events.events[-1].summary = a:events.moon . ' ' . a:events.events[-1].summary + endif +endfunction + +function! calendar#google#calendar#getHolidays(year, month) abort + let _calendarList = s:cache.get('calendarList') + let calendarList = type(_calendarList) == type({}) ? _calendarList : {} + let events = {} + if type(get(calendarList, 'items')) != type([]) + return events + endif + let [y, m] = [printf('%04d', a:year), printf('%02d', a:month)] + for item in calendarList.items + if !get(item, 'selected') || item.id !~# 'holiday@group.v.calendar.google.com' + continue + endif + unlet! cnt + let cnt = s:event_cache.new(item.id).new(y).new(m).get('information') + if type(cnt) != type({}) || !has_key(cnt, 'summary') + continue + endif + let index = 0 + while 1 + unlet! c + let c = s:event_cache.new(item.id).new(y).new(m).get(index) + if type(c) != type({}) + break + endif + let index += 1 + if type(get(c, 'items')) != type([]) + continue + endif + for itm in c.items + if !(has_key(itm, 'start') && (has_key(itm.start, 'date') || has_key(itm.start, 'dateTime')) + \ && has_key(itm, 'end') && (has_key(itm.end, 'date') || has_key(itm.end, 'dateTime'))) + continue + endif + let date = has_key(itm.start, 'date') ? itm.start.date + \ : has_key(itm.start, 'dateTime') ? matchstr(itm.start.dateTime, '\d\+-\d\+-\d\+') : '' + let ymd = map(split(date, '-'), 'v:val + 0') + let enddate = has_key(itm.end, 'date') ? itm.end.date : has_key(itm.end, 'dateTime') ? matchstr(itm.end.dateTime, '\d\+-\d\+-\d\+') : '' + let endymd = map(split(enddate, '-'), 'v:val + 0') + if len(ymd) != 3 || len(endymd) != 3 + continue + endif + let date = join(ymd, '-') + if has_key(itm.end, 'date') + let endymd = calendar#day#new(endymd[0], endymd[1], endymd[2]).add(-1).get_ymd() + endif + if !has_key(events, date) + let events[date] = { 'events': [], 'hasHoliday': 1 } + endif + call add(events[date].events, + \ extend(itm, + \ { 'calendarId': item.id + \ , 'calendarSummary': item.summary + \ , 'holiday': get(itm, 'summary', '') + \ , 'isHoliday': 1 + \ , 'isMoon': 0 + \ , 'isDayNum': 0 + \ , 'isWeekNum': 0 + \ , 'starttime': '' + \ , 'endtime': '' + \ , 'ymdnum': (((ymd[0] * 100 + ymd[1]) * 100) + ymd[2]) + \ , 'hms': [ 0, 0, 0 ] + \ , 'ymd': ymd + \ , 'endhms': [ 0, 0, 0 ] + \ , 'endymd': endymd })) + endfor + endwhile + endfor + return events +endfunction + +" The optional argument is: +" The first argument: Specify the calendar id. If this argument is given, +" the only one calendar is downloaded. +" The second argument: Initial download. See calendar#google#calendar#initialDownload. +function! calendar#google#calendar#downloadEvents(year, month, ...) abort + let calendarList = calendar#google#calendar#getCalendarList() + let key = join([a:year, a:month], '/') + if a:0 < 1 + let s:initial_download[key] = 2 + endif + let month = a:month + 1 + let year = a:year + if month > 12 + let [year, month] = [year + 1, month - 12] + endif + let [timemin, timemax] = [printf('%04d-%02d-01T00:00:00Z', a:year, a:month), printf('%04d-%02d-01T00:00:00Z', year, month)] + if has_key(g:calendar_google_event_downloading, timemin) + let g:calendar_google_event_downloading[timemin] = 1 + endif + if has_key(calendarList, 'items') && type(calendarList.items) == type([]) && len(calendarList.items) + let [y, m] = [printf('%04d', a:year), printf('%02d', a:month)] + let j = 0 + while j < len(calendarList.items) + let item = calendarList.items[j] + if !get(item, 'selected') || a:0 && item.id !=# a:1 + let j += 1 + continue + endif + unlet! cnt + let cnt = s:event_cache.new(item.id).new(y).new(m).get('information') + if type(cnt) != type({}) || !has_key(cnt, 'summary') || a:0 + let opt = { 'timeMin': timemin, 'timeMax': timemax, 'singleEvents': 'true' } + call calendar#google#client#get_async(s:newid(['download', 0, 0, 0, timemin, timemax, y, m, item.id]), + \ 'calendar#google#calendar#response', + \ calendar#google#calendar#get_url('calendars/' . s:event_cache.escape(item.id) . '/events'), opt) + break + endif + let j += 1 + endwhile + if a:0 > 1 + call calendar#async#new(printf('calendar#google#calendar#initialDownload(%d, %d, %d)', a:year, a:month, a:2 + 1)) + endif + endif +endfunction + +function! calendar#google#calendar#response(id, response) abort + let calendarList = calendar#google#calendar#getCalendarList() + let [_download, err, j, i, timemin, timemax, year, month, id; rest] = s:getdata(a:id) + let opt = { 'timeMin': timemin, 'timeMax': timemax, 'singleEvents': 'true' } + if a:response.status =~# '^2' + let cnt = calendar#webapi#decode(a:response.content) + let content = type(cnt) == type({}) ? cnt : {} + if has_key(content, 'items') + call s:event_cache.new(id).new(year).new(month).save(i, content) + if i == 0 + call remove(content, 'items') + call s:event_cache.new(id).new(year).new(month).save('information', content) + endif + if has_key(content, 'nextPageToken') + let opt = extend(opt, { 'pageToken': content.nextPageToken }) + call calendar#google#client#get_async(s:newid(['download', err, j, i + 1, timemin, timemax, year, month, id]), + \ 'calendar#google#calendar#response', + \ calendar#google#calendar#get_url('calendars/' . s:event_cache.escape(id) . '/events'), opt) + else + let k = i + 1 + while filereadable(s:event_cache.new(id).new(year).new(month).path(k)) + silent! call s:event_cache.new(id).new(year).new(month).delete(k) + let k += 1 + endwhile + let g:calendar_google_event_download = 2 + let j += 1 + while j < len(calendarList.items) + let item = calendarList.items[j] + if !get(item, 'selected') + let j += 1 + continue + endif + unlet! cnt + let cnt = s:event_cache.new(item.id).new(year).new(month).get('information') + if type(cnt) != type({}) || !has_key(cnt, 'summary') + call calendar#google#client#get_async(s:newid(['download', 0, j, 0, timemin, timemax, year, month, item.id]), + \ 'calendar#google#calendar#response', + \ calendar#google#calendar#get_url('calendars/' . s:event_cache.escape(item.id) . '/events'), opt) + break + endif + let j += 1 + endwhile + if j == len(calendarList.items) + let g:calendar_google_event_download = 3 + silent! let b:calendar.event._updated = 5 + silent! call b:calendar.update() + endif + endif + endif + elseif a:response.status == 401 || a:response.status == 404 + if i == 0 && err == 0 + call calendar#google#client#refresh_token() + call calendar#google#client#get_async(s:newid(['download', err + 1, j, i, timemin, timemax, year, month, id]), + \ 'calendar#google#calendar#response', + \ calendar#google#calendar#get_url('calendars/' . s:event_cache.escape(id) . '/events'), opt) + else + call calendar#google#client#get_async_use_api_key(s:newid(['download', err + 1, j, 0, timemin, timemax, year, month, id]), + \ 'calendar#google#calendar#response', + \ calendar#google#calendar#get_url('calendars/' . s:event_cache.escape(id) . '/events'), opt) + endif + endif +endfunction + +function! calendar#google#calendar#update(calendarId, eventId, title, year, month, ...) abort + let opt = a:0 ? a:1 : {} + if has_key(opt, 'start') + call s:set_timezone(a:calendarId, opt.start) + endif + if has_key(opt, 'end') + call s:set_timezone(a:calendarId, opt.end) + endif + let location = matchstr(a:title, '\%( at \)\@<=.\+$') + let opt = extend(opt, len(location) ? { 'location': location } : {}) + call calendar#google#client#patch_async(s:newid(['update', 0, a:year, a:month, a:calendarId, a:eventId, a:title, opt]), + \ 'calendar#google#calendar#update_response', + \ calendar#google#calendar#get_url('calendars/' . s:event_cache.escape(a:calendarId) . '/events/' . a:eventId), + \ { 'calendarId': a:calendarId, 'eventId': a:eventId }, + \ extend({ 'id': a:eventId, 'summary': a:title }, opt)) +endfunction + +function! calendar#google#calendar#update_response(id, response) abort + let [_update, err, year, month, calendarId, eventId, title, opt; rest] = s:getdata(a:id) + if a:response.status =~# '^2' + call calendar#google#calendar#downloadEvents(year, month, calendarId) + elseif a:response.status == 401 + if err == 0 + call calendar#google#client#refresh_token() + call calendar#google#client#patch_async(s:newid(['update', 1, year, month, calendarId, eventId, title, opt]), + \ 'calendar#google#calendar#update_response', + \ calendar#google#calendar#get_url('calendars/' . s:event_cache.escape(calendarId) . '/events/' . eventId), + \ { 'calendarId': calendarId, 'eventId': eventId }, + \ extend({ 'id': eventId, 'summary': title }, opt)) + else + call calendar#webapi#echo_error(a:response) + endif + else + call calendar#webapi#echo_error(a:response) + endif +endfunction + +function! calendar#google#calendar#insert(calendarId, title, start, end, year, month, ...) abort + let start = a:start =~# 'T\d' && len(a:start) > 10 ? { 'dateTime': a:start } : { 'date': a:start } + let end = a:end =~# 'T\d' && len(a:end) > 10 ? { 'dateTime': a:end } : { 'date': a:end } + let location = matchstr(a:title, '\%( at \)\@<=.\+$') + let opt = len(location) ? { 'location': location } : {} + let recurrence = a:0 ? a:1 : {} + if has_key(recurrence, 'week') || has_key(recurrence, 'day') + call extend(opt, { 'recurrence': [ 'RRULE:' . ( + \ has_key(recurrence, 'week') ? ('FREQ=WEEKLY;COUNT=' . recurrence.week) : + \ has_key(recurrence, 'day') ? ('FREQ=DAILY;COUNT=' . recurrence.day) : + \ '') ] }) + endif + call s:set_timezone(a:calendarId, start) + call s:set_timezone(a:calendarId, end) + call calendar#google#client#post_async(s:newid(['insert', 0, a:year, a:month, a:calendarId, start, end, a:title, opt]), + \ 'calendar#google#calendar#insert_response', + \ calendar#google#calendar#get_url('calendars/' . s:event_cache.escape(a:calendarId) . '/events'), + \ { 'calendarId': a:calendarId }, + \ extend({ 'summary': a:title, 'start': start, 'end': end, 'transparency': 'transparent' }, opt)) +endfunction + +function! calendar#google#calendar#insert_response(id, response) abort + let [_insert, err, year, month, calendarId, start, end, title, opt; rest] = s:getdata(a:id) + if a:response.status =~# '^2' + call calendar#google#calendar#downloadEvents(year, month, calendarId) + elseif a:response.status == 401 + if err == 0 + call calendar#google#client#refresh_token() + call calendar#google#client#post_async(s:newid(['insert', 1, year, month, calendarId, start, end, title, opt]), + \ 'calendar#google#calendar#insert_response', + \ calendar#google#calendar#get_url('calendars/' . s:event_cache.escape(calendarId) . '/events'), + \ { 'calendarId': calendarId }, + \ extend({ 'summary': title, 'start': start, 'end': end, 'transparency': 'transparent' }, opt)) + endif + else + call calendar#webapi#echo_error(a:response) + endif +endfunction + +function! calendar#google#calendar#move(calendarId, eventId, destination, year, month) abort + call calendar#google#client#post_async(s:newid(['move', 0, a:year, a:month, a:calendarId, a:eventId, a:destination]), + \ 'calendar#google#calendar#move_response', + \ calendar#google#calendar#get_url('calendars/' . s:event_cache.escape(a:calendarId) . '/events/' . a:eventId . '/move'), + \ { 'destination': a:destination }, {}) +endfunction + +function! calendar#google#calendar#move_response(id, response) abort + let [_move, err, year, month, calendarId, eventId, destination; rest] = s:getdata(a:id) + if a:response.status =~# '^2' + call calendar#google#calendar#downloadEvents(year, month, calendarId) + call calendar#google#calendar#downloadEvents(year, month, destination) + elseif a:response.status == 401 + if err == 0 + call calendar#google#client#refresh_token() + call calendar#google#client#patch_async(s:newid(['move', 1, year, month, calendarId, eventId, destination]), + \ 'calendar#google#calendar#move_response', + \ calendar#google#calendar#get_url('calendars/' . s:event_cache.escape(calendarId) . '/events/' . eventId . '/move'), + \ { 'destination': destination }, {}) + else + call calendar#webapi#echo_error(a:response) + endif + else + call calendar#webapi#echo_error(a:response) + endif +endfunction + +function! calendar#google#calendar#delete(calendarId, eventId, year, month) abort + call calendar#google#client#delete_async(s:newid(['delete', 0, a:year, a:month, a:calendarId, a:eventId]), + \ 'calendar#google#calendar#delete_response', + \ calendar#google#calendar#get_url('calendars/' . s:event_cache.escape(a:calendarId) . '/events/' . a:eventId), + \ { 'calendarId': a:calendarId, 'eventId': a:eventId }, {}) +endfunction + +function! calendar#google#calendar#delete_response(id, response) abort + let [_delete, err, year, month, calendarId, eventId; rest] = s:getdata(a:id) + if a:response.status =~# '^2' || a:response.status ==# '410' + call calendar#google#calendar#downloadEvents(year, month, calendarId) + elseif a:response.status == 401 + if err == 0 + call calendar#google#client#refresh_token() + call calendar#google#client#delete_async(s:newid(['delete', 1, year, month, calendarId, eventId]), + \ 'calendar#google#calendar#delete_response', + \ calendar#google#calendar#get_url('calendars/' . s:event_cache.escape(calendarId) . '/events/' . eventId), + \ { 'calendarId': calendarId, 'eventId': eventId }) + else + call calendar#webapi#echo_error(a:response) + endif + else + call calendar#webapi#echo_error(a:response) + endif +endfunction + +function! s:set_timezone(calendarId, obj) abort + let timezone = calendar#setting#get('time_zone') + if has_key(a:obj, 'dateTime') + let a:obj.dateTime .= timezone + else + let a:obj.timeZone = timezone + endif + if has_key(a:obj, 'dateTime') + let a:obj.date = function('calendar#webapi#null') + elseif has_key(a:obj, 'date') + let a:obj.dateTime = function('calendar#webapi#null') + endif +endfunction + +let s:id_data = {} +function! s:newid(data) abort + let id = join([ 'google', 'calendar', a:data[0] ], '_') . '_' . calendar#util#id() + let s:id_data[id] = a:data + return id +endfunction + +function! s:getdata(id) abort + return s:id_data[a:id] +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/google/client.vim b/bundle/calendar.vim/autoload/calendar/google/client.vim new file mode 100644 index 000000000..c2c587173 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/google/client.vim @@ -0,0 +1,196 @@ +" ============================================================================= +" Filename: autoload/calendar/google/client.vim +" Author: itchyny +" License: MIT License +" Last Change: 2020/11/30 20:02:44. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +let s:cache = calendar#cache#new('google') + +let s:auth_url = 'https://accounts.google.com/o/oauth2/auth' + +let s:token_url = 'https://accounts.google.com/o/oauth2/token' + +function! s:client() abort + return extend(deepcopy(calendar#setting#get('google_client')), { 'response_type': 'code' }) +endfunction + +function! s:get_url() abort + let client = s:client() + let param = {} + for x in ['client_id', 'redirect_uri', 'scope', 'response_type'] + if has_key(client, x) + let param[x] = client[x] + endif + endfor + return s:auth_url . '?' . calendar#webapi#encodeURI(param) +endfunction + +function! calendar#google#client#access_token() abort + let cache = s:cache.get('access_token') + if type(cache) != type({}) || type(cache) == type({}) && !has_key(cache, 'access_token') + call calendar#google#client#initialize_access_token() + let cache = s:cache.get('access_token') + if type(cache) != type({}) || type(cache) == type({}) && !has_key(cache, 'access_token') + return 1 + endif + let content = cache + else + let content = cache + endif + return content.access_token +endfunction + +function! calendar#google#client#initialize_access_token() abort + let client = s:client() + let url = s:get_url() + call calendar#webapi#open_url(url) + try + let code = input(printf(calendar#message#get('access_url_input_code'), url) . "\n" . calendar#message#get('input_code')) + catch + return + endtry + if code !=# '' + let response = calendar#webapi#post_nojson(s:token_url, {}, { + \ 'client_id': client.client_id, + \ 'client_secret': client.client_secret, + \ 'code': code, + \ 'redirect_uri': client.redirect_uri, + \ 'grant_type': 'authorization_code'}) + let content = calendar#webapi#decode(response.content) + if calendar#google#client#access_token_response(response, content) + return + endif + else + return + endif + let g:calendar_google_event_downloading_list = 0 + let g:calendar_google_event_download = 3 + silent! let b:calendar.event._updated = 3 +endfunction + +function! calendar#google#client#refresh_token() abort + let client = s:client() + let cache = s:cache.get('refresh_token') + if type(cache) == type({}) && has_key(cache, 'refresh_token') && type(cache.refresh_token) == type('') + let response = calendar#webapi#post_nojson(s:token_url, {}, { + \ 'client_id': client.client_id, + \ 'client_secret': client.client_secret, + \ 'refresh_token': cache.refresh_token, + \ 'grant_type': 'refresh_token'}) + let content = calendar#webapi#decode(response.content) + if calendar#google#client#access_token_response(response, content) + return 1 + endif + return content.access_token + else + return 1 + endif +endfunction + +function! calendar#google#client#access_token_response(response, content) abort + if a:response.status == 200 + if !has_key(a:content, 'access_token') + call calendar#echo#error_message('google_access_token_fail') + return 1 + else + call s:cache.save('access_token', a:content) + if has_key(a:content, 'refresh_token') && type(a:content.refresh_token) == type('') + call s:cache.save('refresh_token', { 'refresh_token': a:content.refresh_token }) + endif + endif + else + call calendar#echo#error_message('google_access_token_fail') + return 1 + endif +endfunction + +function! calendar#google#client#get(url, ...) abort + return s:request('get', a:url, a:0 ? a:1 : {}, a:0 > 1 ? a:2 : {}) +endfunction + +function! calendar#google#client#put(url, ...) abort + return s:request('put', a:url, a:0 ? a:1 : {}, a:0 > 1 ? a:2 : {}) +endfunction + +function! calendar#google#client#post(url, ...) abort + return s:request('post', a:url, a:0 ? a:1 : {}, a:0 > 1 ? a:2 : {}) +endfunction + +function! calendar#google#client#delete(url, ...) abort + return s:request('delete', a:url, a:0 ? a:1 : {}, a:0 > 1 ? a:2 : {}) +endfunction + +function! s:request(method, url, param, body) abort + let client = s:client() + let access_token = calendar#google#client#access_token() + if type(access_token) != type('') + return 1 + endif + let param = extend(a:param, { 'oauth_token': access_token }) + let response = calendar#webapi#{a:method}(a:url, param, a:body) + if response.status == 200 + return calendar#webapi#decode(response.content) + elseif response.status == 401 + unlet! access_token + let access_token = calendar#google#client#refresh_token() + if type(access_token) != type('') + return 1 + endif + let param = extend(a:param, { 'oauth_token': access_token }) + let response = calendar#webapi#{a:method}(a:url, param, a:body) + if response.status == 200 + return calendar#webapi#decode(response.content) + endif + endif + return 1 +endfunction + +function! calendar#google#client#get_async(id, cb, url, ...) abort + call s:request_async(a:id, a:cb, 'get', a:url, a:0 ? a:1 : {}, a:0 > 1 ? a:2 : {}) +endfunction + +function! calendar#google#client#delete_async(id, cb, url, ...) abort + call s:request_async(a:id, a:cb, 'delete', a:url, a:0 ? a:1 : {}, a:0 > 1 ? a:2 : {}) +endfunction + +function! calendar#google#client#put_async(id, cb, url, ...) abort + call s:request_async(a:id, a:cb, 'put', a:url, a:0 ? a:1 : {}, a:0 > 1 ? a:2 : {}) +endfunction + +function! calendar#google#client#patch_async(id, cb, url, ...) abort + call s:request_async(a:id, a:cb, 'patch', a:url, a:0 ? a:1 : {}, a:0 > 1 ? a:2 : {}) +endfunction + +function! calendar#google#client#post_async(id, cb, url, ...) abort + call s:request_async(a:id, a:cb, 'post', a:url, a:0 ? a:1 : {}, a:0 > 1 ? a:2 : {}) +endfunction + +function! s:request_async(id, cb, method, url, param, body) abort + let access_token = calendar#google#client#access_token() + if type(access_token) != type('') + return 1 + endif + let param = extend(a:param, { 'oauth_token': access_token }) + call calendar#webapi#{a:method}_async(a:id, a:cb, a:url, param, a:body) +endfunction + +function! calendar#google#client#get_async_use_api_key(id, cb, url, ...) abort + call s:request_async_use_api_key(a:id, a:cb, 'get', a:url, a:0 ? a:1 : {}, a:0 > 1 ? a:2 : {}) +endfunction + +function! calendar#google#client#post_async_use_api_key(id, cb, url, ...) abort + call s:request_async_use_api_key(a:id, a:cb, 'post', a:url, a:0 ? a:1 : {}, a:0 > 1 ? a:2 : {}) +endfunction + +function! s:request_async_use_api_key(id, cb, method, url, param, body) abort + let client = s:client() + let param = extend(a:param, { 'key': client.api_key }) + call calendar#webapi#{a:method}_async(a:id, a:cb, a:url, param, a:body) +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/google/task.vim b/bundle/calendar.vim/autoload/calendar/google/task.vim new file mode 100644 index 000000000..0eaf7981a --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/google/task.vim @@ -0,0 +1,440 @@ +" ============================================================================= +" Filename: autoload/calendar/google/task.vim +" Author: itchyny +" License: MIT License +" Last Change: 2021/09/18 13:24:16. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +let s:cache = calendar#cache#new('google') + +let s:task_cache = s:cache.new('task') + +function! calendar#google#task#get_url(type) abort + return 'https://www.googleapis.com/tasks/v1/' . a:type +endfunction + +function! calendar#google#task#getTaskList() abort + let taskList = s:cache.get('taskList') + if type(taskList) != type({}) || calendar#timestamp#update('google_tasklist', 7 * 24 * 60 * 60) + call calendar#google#client#get_async(s:newid(['taskList', 0]), + \ 'calendar#google#task#getTaskList_response', + \ calendar#google#task#get_url('users/@me/lists')) + if type(taskList) != type({}) + return {} + endif + endif + return taskList +endfunction + +function! calendar#google#task#getTaskList_response(id, response) abort + let [_tasklist, err; rest] = s:getdata(a:id) + if a:response.status =~# '^2' + let cnt = calendar#webapi#decode(a:response.content) + let content = type(cnt) == type({}) ? cnt : {} + if has_key(content, 'items') && type(content.items) == type([]) + call s:cache.save('taskList', content) + silent! let b:calendar.task._updated = 1 + silent! call b:calendar.update() + endif + elseif a:response.status == 401 + if err == 0 + call calendar#google#client#refresh_token() + call calendar#google#client#get_async(s:newid(['taskList', err + 1]), + \ 'calendar#google#task#getTaskList_response', + \ calendar#google#task#get_url('users/@me/lists')) + endif + endif +endfunction + +function! calendar#google#task#getTasks() abort + if calendar#timestamp#update('google_task', 30 * 60) + call calendar#async#new('calendar#google#task#downloadTasks(1)') + endif + let allTaskList = [] + let taskList = calendar#google#task#getTaskList() + if has_key(taskList, 'items') && type(taskList.items) == type([]) + for tasklist in taskList.items + call add(allTaskList, tasklist) + let allTaskList[-1].items = [] + unlet! cnt + let cnt = s:task_cache.new(tasklist.id).get('information') + if type(cnt) == type({}) && cnt != {} + let i = 0 + let allTaskList[-1].etag = cnt.etag + let items = [] + while type(cnt) == type({}) + unlet! cnt + let cnt = s:task_cache.new(tasklist.id).get(i) + if type(cnt) == type({}) && cnt != {} && has_key(cnt, 'items') && type(cnt.items) == type([]) + call extend(items, cnt.items) + endif + let i += 1 + endwhile + for item in items + if has_key(item, 'due') && item.due =~# '\v\d+-\d+-\d+T' + let [y, m, d] = map(split(substitute(substitute(item.due, 'T.*', '', ''), '\s', '', 'g'), '[-/]'), 'substitute(v:val, "^0", "", "") + 0') + let item.title = calendar#day#join_date([y, m, d]) . ' ' . get(item, 'title', '') + call remove(item, 'due') + endif + if has_key(item, 'notes') && item.notes !=# '' + let item.title = get(item, 'title', '') . ' note: ' . get(item, 'notes', '') + endif + endfor + call sort(items, function('calendar#google#task#sorter')) + let i = 0 + while i < len(items) + if !has_key(items[i], 'parent') + break + endif + let j = i + 1 + let items[i].prefix = ' +- ' + while j < len(items) + if items[j].id ==# items[i].parent + while j < len(items) - 1 + if get(items[j + 1], 'parent', '') ==# items[i].parent + let items[j + 1].prefix = ' |- ' + let j += 1 + else + break + endif + endwhile + call insert(items, items[i], j + 1) + call remove(items, i) + let i -= 1 + break + endif + let j += 1 + endwhile + let i += 1 + endwhile + let allTaskList[-1].items = items + else + call calendar#google#task#downloadTasks() + endif + endfor + endif + return allTaskList +endfunction + +function! calendar#google#task#sorter(x, y) abort + return has_key(a:x, 'parent') != has_key(a:y, 'parent') + \ ? (has_key(a:x, 'parent') ? -1 : 1) + \ : a:x.position ==# a:y.position + \ ? (a:x.updated > a:y.updated ? 1 : -1) + \ : a:x.position > a:y.position ? 1 : -1 +endfunction + +" Optional argument: Force download. +function! calendar#google#task#downloadTasks(...) abort + let taskList = calendar#google#task#getTaskList() + if has_key(taskList, 'items') && type(taskList.items) == type([]) && len(taskList.items) + let j = 0 + while j < len(taskList.items) + let item = taskList.items[j] + unlet! cnt + let cnt = s:task_cache.new(item.id).get('information') + if type(cnt) != type({}) || cnt == {} || get(a:000, 0) && (a:0 <= 1 || item.id ==# get(a:000, 1, '')) + let opt = { 'tasklist': item.id, 'maxResults': 100 } + call calendar#google#client#get_async(s:newid(['download', 0, j, 0, item.id, a:000]), + \ 'calendar#google#task#response', + \ calendar#google#task#get_url('lists/' . item.id . '/tasks'), opt) + break + endif + let j += 1 + endwhile + if j == len(taskList.items) + silent! let b:calendar.task._updated = 1 + silent! call b:calendar.update() + endif + endif +endfunction + +function! calendar#google#task#response(id, response) abort + let taskList = calendar#google#task#getTaskList() + let [_download, err, j, i, id, force; rest] = s:getdata(a:id) + let opt = { 'tasklist': id } + if a:response.status =~# '^2' + let cnt = calendar#webapi#decode(a:response.content) + let content = type(cnt) == type({}) ? cnt : {} + if has_key(content, 'items') + call s:task_cache.new(id).save(i, content) + if i == 0 + call remove(content, 'items') + call s:task_cache.new(id).save('information', content) + endif + if has_key(content, 'nextPageToken') + let opt = extend(opt, { 'pageToken': content.nextPageToken }) + call calendar#google#client#get_async(s:newid(['download', err, j, i + 1, id, force]), + \ 'calendar#google#task#response', + \ calendar#google#task#get_url('lists/' . id . '/tasks'), opt) + else + let k = i + 1 + while filereadable(s:task_cache.new(id).path(k)) + silent! call s:task_cache.new(id).delete(k) + let k += 1 + endwhile + let j += 1 + while j < len(taskList.items) + let item = taskList.items[j] + unlet! cnt + let cnt = s:task_cache.new(item.id).get('information') + let opt = { 'tasklist': item.id, 'maxResults': 100 } + if type(cnt) != type({}) || cnt == {} || get(force, 0) && (len(force) <= 1 || item.id ==# get(force, 1, '')) + call calendar#google#client#get_async(s:newid(['download', 0, j, 0, item.id, force]), + \ 'calendar#google#task#response', + \ calendar#google#task#get_url('lists/' . item.id . '/tasks'), opt) + break + endif + let j += 1 + endwhile + if j == len(taskList.items) + silent! let b:calendar.task._updated = 1 + silent! call b:calendar.update() + endif + endif + elseif i == 0 && has_key(content, 'etag') + let k = 0 + while filereadable(s:task_cache.new(id).path(k)) + silent! call s:task_cache.new(id).delete(k) + let k += 1 + endwhile + if k > 0 + silent! let b:calendar.task._updated = 1 + silent! call b:calendar.update() + endif + endif + elseif a:response.status == 401 + if i == 0 && err == 0 + let opt = { 'tasklist': id } + call calendar#google#client#refresh_token() + call calendar#google#client#get_async(s:newid(['download', err + 1, j, i, id, force]), + \ 'calendar#google#task#response', + \ calendar#google#task#get_url('lists/' . id . '/tasks'), opt) + endif + endif +endfunction + +function! calendar#google#task#insert(id, previous, parent, title, ...) abort + let opt = { 'tasklist': a:id } + if a:previous !=# '' + let opt.previous = a:previous + endif + if a:parent !=# '' + let opt.parent = a:parent + endif + let due = '' + if a:0 + let due = get(a:1, 'due', '') + if due !=# '' + let due = due . (due =~# 'Z$' ? '' : 'Z') + endif + endif + let note = '' + if a:title =~# ' note: ' + let note = matchstr(a:title, ' note: .*$') + let title = a:title[:(len(a:title) - len(note)) - 1] + let note = substitute(note, ' note:\s*', '', '') + else + let note = '' + let title = a:title + endif + call calendar#google#client#post_async(s:newid(['insert', 0, a:id, title, note, due, opt]), + \ 'calendar#google#task#insert_response', + \ calendar#google#task#get_url('lists/' . a:id . '/tasks'), + \ opt, extend({ 'title': title, 'notes': note }, due ==# '' ? {} : { 'due': due ==# '-1Z' ? function('calendar#webapi#null') : due })) +endfunction + +function! calendar#google#task#insert_response(id, response) abort + let [_insert, err, id, title, note, due, opt; rest] = s:getdata(a:id) + if a:response.status =~# '^2' + call calendar#google#task#downloadTasks(1, id) + elseif a:response.status == 401 + if err == 0 + call calendar#google#client#refresh_token() + call calendar#google#client#post_async(s:newid(['insert', 1, id, title, note, due, opt]), + \ 'calendar#google#task#insert_response', + \ calendar#google#task#get_url('lists/' . id . '/tasks'), + \ opt, extend({ 'title': title, 'notes': note }, due ==# '' ? {} : { 'due': due ==# '-1Z' ? function('calendar#webapi#null') : due })) + endif + endif +endfunction + +function! calendar#google#task#move(id, taskid, previous, parent) abort + let opt = { 'tasklist': a:id } + if a:previous !=# '' + let opt.previous = a:previous + endif + if a:parent !=# '' + let opt.parent = a:parent + endif + call calendar#google#client#post_async(s:newid(['move', 0, a:id, a:taskid, opt]), + \ 'calendar#google#task#move_response', + \ calendar#google#task#get_url('lists/' . a:id . '/tasks/' . a:taskid . '/move'), + \ opt, {}) +endfunction + +function! calendar#google#task#move_response(id, response) abort + let [_move, err, id, taskid, opt; rest] = s:getdata(a:id) + if a:response.status =~# '^2' + call calendar#google#task#downloadTasks(1, id) + elseif a:response.status == 401 + if err == 0 + call calendar#google#client#refresh_token() + call calendar#google#client#post_async(s:newid(['move', 1, id, taskid, opt]), + \ 'calendar#google#task#move_response', + \ calendar#google#task#get_url('lists/' . id . '/tasks/' . taskid . '/move'), + \ opt, {}) + endif + endif +endfunction + +function! calendar#google#task#clear_completed(id) abort + call calendar#google#client#post_async(s:newid(['clear_completed', 0, a:id]), + \ 'calendar#google#task#clear_completed_response', + \ calendar#google#task#get_url('lists/' . a:id . '/clear'), + \ { 'tasklist': a:id }) +endfunction + +function! calendar#google#task#clear_completed_response(id, response) abort + let [_clear_completed, err, id; rest] = s:getdata(a:id) + if a:response.status =~# '^2' + call calendar#google#task#downloadTasks(1, id) + elseif a:response.status == 401 + if err == 0 + call calendar#google#client#refresh_token() + call calendar#google#client#post_async(s:newid(['clear_completed', 1, id]), + \ 'calendar#google#task#clear_completed_response', + \ calendar#google#task#get_url('lists/' . id . '/clear'), + \ { 'tasklist': id }) + endif + endif +endfunction + +function! calendar#google#task#update(id, taskid, title, ...) abort + let due = '' + if a:0 + let due = get(a:1, 'due', '') + if due !=# '' + let due = due . (due =~# 'Z$' ? '' : 'Z') + endif + endif + let note = '' + if a:title =~# ' note: ' + let note = matchstr(a:title, ' note: .*$') + let title = a:title[:(len(a:title) - len(note)) - 1] + let note = substitute(note, ' note:\s*', '', '') + else + let note = '' + let title = a:title + endif + call calendar#google#client#put_async(s:newid(['update', 0, a:id, a:taskid, title, note, due]), + \ 'calendar#google#task#update_response', + \ calendar#google#task#get_url('lists/' . a:id . '/tasks/' . a:taskid), + \ { 'tasklist': a:id, 'task': a:taskid }, + \ extend({ 'id': a:taskid, 'title': title, 'notes': note }, due ==# '' ? {} : { 'due': due ==# '-1Z' ? function('calendar#webapi#null') : due })) +endfunction + +function! calendar#google#task#update_response(id, response) abort + let [_update, err, id, taskid, title, note, due; rest] = s:getdata(a:id) + if a:response.status =~# '^2' + call calendar#google#task#downloadTasks(1, id) + elseif a:response.status == 401 + if err == 0 + call calendar#google#client#refresh_token() + call calendar#google#client#put_async(s:newid(['update', 1, id, taskid, title, note, due]), + \ 'calendar#google#task#update_response', + \ calendar#google#task#get_url('lists/' . id . '/tasks/' . taskid), + \ { 'tasklist': id, 'task': taskid }, + \ extend({ 'id': taskid, 'title': title, 'notes': note }, due ==# '' ? {} : { 'due': due ==# '-1Z' ? function('calendar#webapi#null') : due })) + endif + endif +endfunction + +function! calendar#google#task#complete(id, taskid) abort + call calendar#google#client#patch_async(s:newid(['complete', 0, a:id, a:taskid]), + \ 'calendar#google#task#complete_response', + \ calendar#google#task#get_url('lists/' . a:id . '/tasks/' . a:taskid), + \ { 'tasklist': a:id, 'task': a:taskid }, + \ { 'id': a:taskid, 'status': 'completed' }) +endfunction + +function! calendar#google#task#complete_response(id, response) abort + let [_complete, err, id, taskid; rest] = s:getdata(a:id) + if a:response.status =~# '^2' + call calendar#google#task#downloadTasks(1, id) + elseif a:response.status == 401 + if err == 0 + call calendar#google#client#refresh_token() + call calendar#google#client#patch_async(s:newid(['complete', 1, id, taskid]), + \ 'calendar#google#task#complete_response', + \ calendar#google#task#get_url('lists/' . id . '/tasks/' . taskid), + \ { 'tasklist': id, 'task': taskid }, + \ { 'id': taskid, 'status': 'completed' }) + endif + endif +endfunction + +function! calendar#google#task#uncomplete(id, taskid) abort + call calendar#google#client#patch_async(s:newid(['uncomplete', 0, a:id, a:taskid]), + \ 'calendar#google#task#uncomplete_response', + \ calendar#google#task#get_url('lists/' . a:id . '/tasks/' . a:taskid), + \ { 'tasklist': a:id, 'task': a:taskid }, + \ { 'id': a:taskid, 'status': 'needsAction' }) +endfunction + +function! calendar#google#task#uncomplete_response(id, response) abort + let [_uncomplete, err, id, taskid; rest] = s:getdata(a:id) + if a:response.status =~# '^2' + call calendar#google#task#downloadTasks(1, id) + elseif a:response.status == 401 + if err == 0 + call calendar#google#client#refresh_token() + call calendar#google#client#patch_async(s:newid(['uncomplete', 1, id, taskid]), + \ 'calendar#google#task#uncomplete_response', + \ calendar#google#task#get_url('lists/' . id . '/tasks/' . taskid), + \ { 'tasklist': id, 'task': taskid }, + \ { 'id': taskid, 'status': 'needsAction' }) + endif + endif +endfunction + +function! calendar#google#task#delete(id, taskid) abort + call calendar#google#client#delete_async(s:newid(['delete', 0, a:id, a:taskid]), + \ 'calendar#google#task#delete_response', + \ calendar#google#task#get_url('lists/' . a:id . '/tasks/' . a:taskid), + \ { 'tasklist': a:id, 'task': a:taskid }, + \ { 'id': a:taskid }) +endfunction + +function! calendar#google#task#delete_response(id, response) abort + let [_delete, err, id, taskid; rest] = s:getdata(a:id) + if a:response.status =~# '^2' + call calendar#google#task#downloadTasks(1, id) + elseif a:response.status == 401 + if err == 0 + call calendar#google#client#refresh_token() + call calendar#google#client#delete_async(s:newid(['delete', 1, id, taskid]), + \ 'calendar#google#task#delete_response', + \ calendar#google#task#get_url('lists/' . id . '/tasks/' . taskid), + \ { 'tasklist': id, 'task': taskid }, + \ { 'id': taskid }) + endif + endif +endfunction + +let s:id_data = {} +function! s:newid(data) abort + let id = join([ 'google', 'task', a:data[0] ], '_') . '_' . calendar#util#id() + let s:id_data[id] = a:data + return id +endfunction + +function! s:getdata(id) abort + return s:id_data[a:id] +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/mapping.vim b/bundle/calendar.vim/autoload/calendar/mapping.vim new file mode 100644 index 000000000..9a9a54ddc --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/mapping.vim @@ -0,0 +1,243 @@ +" ============================================================================= +" Filename: autoload/calendar/mapping.vim +" Author: itchyny +" License: MIT License +" Last Change: 2019/08/07 21:21:45. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +" Setting mappings in the calendar buffer. + +function! calendar#mapping#new() abort + + let save_cpo = &cpo + set cpo&vim + + if has_key(get(b:, 'calendar', {}), 'view') + let v = b:calendar.view + if maparg('', 'n') !=# '(calendar_escape)' + if v.help_visible() || v.event_visible() || v.task_visible() || b:calendar.visual_mode() + if v:version > 703 + nmap (calendar_escape) + else + nmap (calendar_escape) + endif + endif + else + if !(v.help_visible() || v.event_visible() || v.task_visible() || b:calendar.visual_mode()) + nunmap + endif + endif + endif + if &l:filetype ==# 'calendar' + let &cpo = save_cpo + return + endif + + " normal mode mapping + let actions = ['left', 'right', 'down', 'up', 'prev', 'next', 'move_down', 'move_up', 'move_event', + \ 'down_big', 'up_big', 'down_large', 'up_large', + \ 'line_head', 'line_middle', 'line_last', 'bar', + \ 'first_line', 'last_line', 'first_line_head', 'last_line_last', 'space', + \ 'scroll_down', 'scroll_up', 'scroll_top_head', 'scroll_top', + \ 'scroll_center_head', 'scroll_center', 'scroll_bottom_head', 'scroll_bottom', + \ 'add', 'subtract', 'status', 'plus', 'minus', 'task', 'event', 'close_task', 'close_event', + \ 'delete', 'delete_line', 'yank', 'yank_line', 'change', 'change_line', + \ 'undo', 'undo_line', 'tab', 'shift_tab', 'next_match', 'prev_match', + \ 'today', 'enter', 'view_left', 'view_right', 'redraw', 'clear', 'help', 'hide', 'exit', + \ 'visual', 'visual_line', 'visual_block', 'exit_visual', + \ 'start_insert', 'start_insert_append', 'start_insert_head', 'start_insert_last', + \ 'start_insert_prev_line', 'start_insert_next_line', 'start_insert_quick', + \ ] + for action in actions + exec printf("nnoremap (calendar_%s) :call b:calendar.action('%s')", action, action) + endfor + + " escape + nmap (calendar_escape) + \ b:calendar.view.help_visible() ? "\(calendar_help)" : + \ b:calendar.view.event_visible() ? "\(calendar_event)" : + \ b:calendar.visual_mode() ? "\(calendar_exit_visual)" : + \ b:calendar.view.task_visible() ? "\(calendar_task)" : + \ "" + + " mark + let marks = map(range(97, 97 + 25), 'nr2char(v:val)') + for mark in marks + exec printf("nmap m%s :call b:calendar.mark.set('%s')", mark, mark) + exec printf("nmap `%s :call b:calendar.mark.get('%s')", mark, mark) + exec printf("nmap '%s :call b:calendar.mark.get('%s')", mark, mark) + exec printf("nmap g`%s :call b:calendar.mark.get('%s')", mark, mark) + exec printf("nmap g'%s :call b:calendar.mark.get('%s')", mark, mark) + endfor + for mark in ['`', "'"] + exec printf("nmap %s%s :call b:calendar.mark.get('%s')", mark, mark, mark ==# "'" ? mark . mark : mark) + endfor + + " command line mapping + cnoremap (calendar_command_enter) b:calendar.action('command_enter') + + " move neighborhood + nmap h (calendar_left) + nmap l (calendar_right) + nmap j (calendar_down) + nmap k (calendar_up) + nmap (calendar_left) + nmap (calendar_right) + nmap (calendar_down) + nmap (calendar_up) + nmap h + nmap h + nmap gh h + nmap gl l + nmap gj j + nmap gk k + nmap g + nmap g + nmap g + nmap g + nmap + nmap + nmap (calendar_down) + nmap (calendar_up) + nmap (calendar_move_down) + nmap (calendar_move_up) + nmap (calendar_move_down) + nmap (calendar_move_up) + nmap M (calendar_move_event) + nmap w (calendar_next) + nmap W w + nmap e w + nmap w + nmap w + nmap b (calendar_prev) + nmap B b + nmap ge b + nmap gE b + nmap b + nmap b + + " move page + nmap (calendar_down_big) + nmap (calendar_up_big) + nmap (calendar_down_large) + nmap (calendar_up_large) + nmap + nmap + + " move column + nmap 0 (calendar_line_head) + nmap ^ 0 + nmap g0 0 + nmap 0 + nmap g 0 + nmap g^ ^ + nmap gm (calendar_line_middle) + nmap $ (calendar_line_last) + nmap g$ $ + nmap g_ $ + nmap $ + nmap g $ + nmap gg (calendar_first_line) + nmap gg + nmap ( (calendar_first_line) + nmap { ( + nmap [[ ( + nmap [] [[ + nmap G (calendar_last_line) + nmap ) (calendar_last_line) + nmap } ) + nmap ]] ) + nmap ][ ]] + nmap (calendar_last_line_last) + nmap (calendar_bar) + + " scroll + nmap (calendar_scroll_down) + nmap (calendar_scroll_up) + nmap z (calendar_scroll_top_head) + nmap zt (calendar_scroll_top) + nmap z. (calendar_scroll_center_head) + nmap zz (calendar_scroll_center) + nmap z- (calendar_scroll_bottom_head) + nmap zb (calendar_scroll_bottom) + + " delete + nmap d (calendar_delete) + nmap D (calendar_delete_line) + + " yank + nmap y (calendar_yank) + nmap Y (calendar_yank_line) + + " change + nmap c (calendar_change) + nmap C (calendar_change_line) + + " utility + nmap (calendar_undo) + nmap u (calendar_undo) + nmap U (calendar_undo_line) + nmap (calendar_tab) + nmap (calendar_shift_tab) + nmap n (calendar_next_match) + nmap N (calendar_prev_match) + nmap t (calendar_today) + nmap (calendar_enter) + nmap (calendar_add) + nmap (calendar_subtract) + nmap (calendar_status) + nmap + (calendar_plus) + nmap - (calendar_minus) + nmap T (calendar_task) + nmap E (calendar_event) + nmap < (calendar_view_left) + nmap > (calendar_view_right) + nmap (calendar_space) + nmap (calendar_redraw) + nmap (calendar_redraw) + nmap L (calendar_clear) + nmap ? (calendar_help) + nmap q (calendar_hide) + nmap Q (calendar_exit) + + " nop + nmap H + nmap J + nmap p + nmap P + nmap r + nmap R + nmap ~ + + " insert mode + nmap i (calendar_start_insert) + nmap a (calendar_start_insert_append) + nmap I (calendar_start_insert_head) + nmap A (calendar_start_insert_last) + nmap O (calendar_start_insert_prev_line) + nmap o (calendar_start_insert_next_line) + + " visual mode + nmap v (calendar_visual) + nmap V (calendar_visual_line) + nmap (calendar_visual_block) + nmap gh v + nmap gH V + nmap g + + " command line + cmap (calendar_command_enter) + + " mouse wheel + map (calendar_prev) + map (calendar_next) + + let &cpo = save_cpo + +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/mark.vim b/bundle/calendar.vim/autoload/calendar/mark.vim new file mode 100644 index 000000000..f9cfdaf6c --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/mark.vim @@ -0,0 +1,56 @@ +" ============================================================================= +" Filename: autoload/calendar/mark.vim +" Author: itchyny +" License: MIT License +" Last Change: 2015/03/29 06:30:36. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +" Mark controller. +function! calendar#mark#new() abort + return extend(copy(s:self), { 'mark': {} }) +endfunction + +let s:self = {} + +function! s:self.set(mark) dict abort + let self.mark[a:mark] = copy(b:calendar.day().get_ymd()) + copy(b:calendar.time().get_hms()) + let self.mark["'"] = self.mark[a:mark] +endfunction + +function! s:self.get(mark) dict abort + let mark = a:mark ==# '`' ? "'" : a:mark + if has_key(self.mark, mark) + let m = self.mark[mark] + call b:calendar.set_time(b:calendar.time().new(m[3], m[4], m[5])) + call b:calendar.go(b:calendar.day().new(m[0], m[1], m[2])) + else + call calendar#echo#message(calendar#message#get('mark_not_set') . mark) + endif +endfunction + +function! s:self.showmarks() dict abort + let marks = ['mark year month day hour minute second'] + let format = '%s %6d %4d %4d %4d %4d %4d' + for [k, m] in items(self.mark) + call add(marks, printf(format, k, m[0], m[1], m[2], m[3], m[4], m[5])) + endfor + call add(marks, calendar#message#get('hit_any_key')) + call calendar#echo#echo(join(marks, "\n")) + call getchar() +endfunction + +function! s:self.delmarks(...) dict abort + if a:0 + if has_key(self.mark, a:1) + unlet self.mark[a:1] + endif + else + let self.mark = {} + endif +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/message.vim b/bundle/calendar.vim/autoload/calendar/message.vim new file mode 100644 index 000000000..51ba28853 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/message.vim @@ -0,0 +1,43 @@ +" ============================================================================= +" Filename: autoload/calendar/message.vim +" Author: itchyny +" License: MIT License +" Last Change: 2015/03/29 06:30:41. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +" Getting the message based on the locale setting. +" The message files are found in message/. +function! calendar#message#get(type) abort + let locale = calendar#setting#get('locale') + try + let message = calendar#message#{locale}#get() + catch + if len(locale) > 1 + try + let message = calendar#message#{locale[:1]}#get() + catch + let message = calendar#message#default#get() + endtry + else + let message = calendar#message#default#get() + endif + finally + if has_key(message, a:type) + return message[a:type] + else + let message = calendar#message#default#get() + if has_key(message, a:type) + return message[a:type] + else + let message = calendar#message#en#get() + return message[a:type] + endif + endif + endtry +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/message/default.vim b/bundle/calendar.vim/autoload/calendar/message/default.vim new file mode 100644 index 000000000..22e5d2c6e --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/message/default.vim @@ -0,0 +1,35 @@ +" ============================================================================= +" Filename: autoload/calendar/message/default.vim +" Author: itchyny +" License: MIT License +" Last Change: 2015/03/29 06:30:38. +" ============================================================================= + +scriptencoding utf-8 + +let s:save_cpo = &cpo +set cpo&vim + +function! calendar#message#default#get() abort + return extend(s:english_message, s:message()) +endfunction + +let s:english_message = deepcopy(calendar#message#en#get()) + +if exists('*strftime') + function! s:message() abort + let message = {} + let message.day_name = map(range(3, 9), "strftime('%a', 60 * 60 * (24 * v:val + 10))") + let message.day_name_long = map(range(3, 9), "strftime('%A', 60 * 60 * (24 * v:val + 10))") + let message.month_name = map(range(12), "strftime('%b', 60 * 60 * 24 * (32 * v:val + 5))") + let message.month_name_long = map(range(12), "strftime('%B', 60 * 60 * 24 * (32 * v:val + 5))") + return message + endfunction +else + function! s:message() abort + return {} + endfunction +endif + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/message/en.vim b/bundle/calendar.vim/autoload/calendar/message/en.vim new file mode 100644 index 000000000..f92df8723 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/message/en.vim @@ -0,0 +1,107 @@ +" ============================================================================= +" Filename: autoload/calendar/message/en.vim +" Author: itchyny +" License: MIT License +" Last Change: 2016/05/09 08:07:17. +" ============================================================================= + +scriptencoding utf-8 + +let s:save_cpo = &cpo +set cpo&vim + +function! calendar#message#en#get() abort + return s:message +endfunction + +let s:message = {} + +let s:message.day_name = [ 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat' ] + +let s:message.day_name_long = [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday' ] + +let s:message.month_name = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ] + +let s:message.month_name_long = [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ] + +let s:message.today = 'today' + +let s:message.multiple_argument = 'There are multiple possible arguments' + +let s:message.mkdir_fail = 'Could not create the directory for cache files' + +let s:message.cache_file_unwritable = 'The cache file is not writable' + +let s:message.cache_write_fail = 'Could not write the cache file' + +let s:message.access_url_input_code = 'Access %s and paste the code' + +let s:message.google_access_token_fail = 'Fail in authorization to Google' + +let s:message.delete_event = 'Delete the event? (cannot be undone) y/N: ' + +let s:message.delete_task = 'Delete the task? (cannot be undone) y/N: ' + +let s:message.clear_completed_task = 'Clear all the completed tasks? (cannot be undone) y/N: ' + +let s:message.curl_wget_not_found = 'curl and wget not found' + +let s:message.mark_not_set = 'Mark not set: ' + +let s:message.start_date_time = 'Starting date and time: ' + +let s:message.end_date_time = 'Ending date and time: ' + +let s:message.input_calendar_index = 'Input the index of the calendar: ' + +let s:message.input_calendar_name = 'Input the name of a new calendar: ' + +let s:message.hit_any_key = '[Hit any key]' + +let s:message.input_code = 'CODE: ' + +let s:message.input_task = 'TASK: ' + +let s:message.input_event = 'EVENT: ' + +let s:message.help = { + \ 'title': calendar#util#name() . ' help', + \ 'message': join([" This is a calendar application for Vim. ", + \ "This calendar provides many views. Press the < and > keys. ", + \ "There are year view, month view, week view, days view, day view and clock view.\n", + \ " This calendar supports to download calendars from Google Calendar and show the events. ", + \ "Add the following configuration to your vimrc file.\n", + \ " let g:calendar_google_calendar = 1\n", + \ "On starting the calendar, it will start authorization. ", + \ "Press the E key to view and edit the events of the selected day. ", + \ "Moreover, you can also download tasks from Google Task with the following configuration.\n", + \ " let g:calendar_google_task = 1\n", + \ "In order to see tasks, press the T key. You can edit and create tasks in the task window.\n", + \ " For more information, open the help file with the following command.\n", + \ " :help calendar\n", + \ ], ''), + \ 'credit': join([" Name: " . calendar#util#name(), + \ " Version: " . calendar#util#version(), + \ " Author: " . calendar#util#author(), + \ " License: " . calendar#util#license(), + \ " Repository: " . calendar#util#repository(), + \ " Bug tracker: " . calendar#util#issue(), + \ ], "\n"), + \ 'view_left': 'Left view', + \ 'view_right': 'Right view', + \ 'today': 'Go to today', + \ 'task': 'Toggle task window', + \ 'event': 'Toggle event window', + \ 'delete_line': 'Delete the event / Complete the task', + \ 'clear': 'Clear completed tasks', + \ 'undo_line': 'Uncomplete the task', + \ 'help': 'Toggle this help', + \ 'exit': 'Exit', + \ } + +let s:message.task = { + \ 'title': 'Task list', + \ } + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/message/ja.vim b/bundle/calendar.vim/autoload/calendar/message/ja.vim new file mode 100644 index 000000000..11c3029df --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/message/ja.vim @@ -0,0 +1,113 @@ +" ============================================================================= +" Filename: autoload/calendar/message/ja.vim +" Author: itchyny +" License: MIT License +" Last Change: 2016/05/09 08:06:55. +" ============================================================================= + +scriptencoding utf-8 + +let s:save_cpo = &cpo +set cpo&vim + +function! calendar#message#ja#get() abort + return s:message +endfunction + +let s:message = {} + +let s:message.day_name = [ '日', '月', '火', '水', '木', '金', '土' ] + +let s:message.day_name_long = [ '日曜日', '月曜日', '火曜日', '水曜日', '木曜日', '金曜日', '土曜日' ] + +let s:message.month_name = [ '1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月' ] + +let s:message.month_name_long = s:message.month_name + +let s:message.today = '今日' + +let s:message.multiple_argument = '複数の引数候補があります' + +let s:message.mkdir_fail = 'キャッシュ用のディレクトリーの作成に失敗しました' + +let s:message.cache_file_unwritable = 'キャッシュファイルの書き込みが許されていません' + +let s:message.cache_write_fail = 'キャッシュファイルの書き込みに失敗しました' + +let s:message.access_url_input_code = '%s にアクセスして、コードを入力して下さい' + +let s:message.google_access_token_fail = 'Googleへの認証に失敗しました' + +let s:message.delete_event = 'イベントを削除しますか? (この操作は元に戻せません) y/N: ' + +let s:message.delete_task = 'タスクを削除しますか? (この操作は元に戻せません) y/N: ' + +let s:message.clear_completed_task = '完了したタスクを全て削除しますか? (この操作は元に戻せません) y/N: ' + +let s:message.curl_wget_not_found = 'curl または wget が必要です' + +let s:message.mark_not_set = 'マークが設定されていません: ' + +let s:message.start_date_time = '開始日時: ' + +let s:message.end_date_time = '終了日時: ' + +let s:message.input_calendar_index = 'カレンダーの番号を指定して下さい: ' + +let s:message.input_calendar_name = '新しいカレンダーの名前を入力して下さい: ' + +let s:message.hit_any_key = '[キーを押して下さい]' + +let s:message.input_code = 'コード: ' + +let s:message.input_task = 'タスク: ' + +let s:message.input_event = 'イベント: ' + +let s:message.help = { + \ 'title': calendar#util#name() . ' ヘルプ', + \ 'message': join([" Vimで動くカレンダーアプリケーションです。", + \ "このカレンダーは、様々なビューを備えています。< と > を押してみてください。", + \ "一年のビュー、一か月ビュー、週間ビュー、数日ビュー、一日ビュー、そして時計ビューがあります。\n", + \ " また、Google Calendarからカレンダーをダウンロードし、表示することも出来ます。", + \ "次の設定をvimrcに書いて下さい。\n", + \ " let g:calendar_google_calendar = 1\n", + \ "カレンダーを起動すると、認証が始まります。", + \ "選択した日のイベント一覧を表示したり、編集したりするには、Eを押して下さい。", + \ "また、次の設定を書くとGoogle Taskからあなたのタスクをダウンロードすることも出来ます。\n", + \ " let g:calendar_google_task = 1\n", + \ "タスクを表示するには、Tを押して下さい。", + \ "その画面で、タスクを編集したり新しく作成したりすることも出来ます。\n", + \ " 更に詳細な事は、アプリケーションのヘルプファイルを参照して下さい。\n", + \ " :help calendar\n", + \ ], ''), + \ 'credit': join([" アプリケーション名: " . calendar#util#name(), + \ " バージョン: " . calendar#util#version(), + \ " 作者: " . calendar#util#author(), + \ " ライセンス: " . calendar#util#license(), + \ " リポジトリ: " . calendar#util#repository(), + \ " バグ報告: " . calendar#util#issue(), + \ ], "\n"), + \ 'Credit': 'クレジット', + \ 'Mapping': 'マッピング', + \ 'View': 'ビュー', + \ 'Utility': 'ユーティリティー', + \ 'view_left': '左のビュー', + \ 'view_right': '右のビュー', + \ 'today': '今日', + \ 'Event window / Task window': 'イベントウィンドウ / タスクウィンドウ', + \ 'task': 'タスクウィンドウを表示/非表示', + \ 'event': 'イベントウィンドウを表示/非表示', + \ 'delete_line': 'イベントを削除 / 選択中のタスクを完了状態にする', + \ 'clear': '完了したタスクを全て削除する', + \ 'undo_line': '完了状態にしたタスクを未完にする', + \ 'help': 'このヘルプを表示/非表示', + \ 'exit': 'カレンダーを終了する', + \ } + +let s:message.task = { + \ 'title': 'タスク', + \ } + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/model.vim b/bundle/calendar.vim/autoload/calendar/model.vim new file mode 100644 index 000000000..443c21155 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/model.vim @@ -0,0 +1,156 @@ +" ============================================================================= +" Filename: autoload/calendar/model.vim +" Author: itchyny +" License: MIT License +" Last Change: 2015/03/29 06:31:06. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +" Model object +" This object keeps time, day and month. +function! calendar#model#new() abort + return copy(s:self) +endfunction + +let s:self = {} + +function! s:self.time() dict abort + return self._time +endfunction + +function! s:self.set_time(time) dict abort + let self._time = a:time + return self +endfunction + +function! s:self.second() dict abort + return self._time.second() +endfunction + +function! s:self.minute() dict abort + return self._time.minute() +endfunction + +function! s:self.hour() dict abort + return self._time.hour() +endfunction + +function! s:self.move_second(diff) dict abort + let [d, new_time] = self.time().add_second(a:diff) + call self.set_time(new_time) + call self.move_day(d) +endfunction + +function! s:self.move_minute(diff) dict abort + let [d, new_time] = self.time().add_minute(a:diff) + call self.set_time(new_time) + call self.move_day(d) +endfunction + +function! s:self.move_hour(diff) dict abort + let [d, new_time] = self.time().add_hour(a:diff) + call self.set_time(new_time) + call self.move_day(d) +endfunction + +function! s:self.day() dict abort + return self._day +endfunction + +function! s:self.set_day(day) dict abort + let self._day = a:day + return self +endfunction + +function! s:self.month() dict abort + return self._month +endfunction + +function! s:self.set_month(month) dict abort + let self._month = a:month + return self +endfunction + +function! s:self.set_month_from_day() dict abort + return self.set_month(self.day().month()) +endfunction + +function! s:self.year() dict abort + return self._day.year() +endfunction + +function! s:self.get_days() dict abort + return self.month().get_days() +endfunction + +function! s:self.move_day(diff) dict abort + let new_day = self.day().add(a:diff) + call self.set_day(new_day) + if !self.month().eq(new_day.month()) + call self.set_month_from_day() + endif +endfunction + +function! s:self.move_month(diff) dict abort + call self.set_day(self.day().add_month(a:diff)) + call self.set_month_from_day() +endfunction + +function! s:self.move_year(diff) dict abort + call self.set_day(self.day().add_year(a:diff)) + call self.set_month_from_day() +endfunction + +function! s:self._start_visual(mode) dict abort + if self.visual_mode() == 0 + let self._visual_start_day = deepcopy(self._day) + let self._visual_start_time = deepcopy(self._time) + endif + let self._visual = get(self, '_visual') == a:mode ? 0 : a:mode +endfunction + +function! s:self.start_visual() dict abort + call self._start_visual(1) +endfunction + +function! s:self.start_line_visual() dict abort + call self._start_visual(2) +endfunction + +function! s:self.start_block_visual() dict abort + call self._start_visual(3) +endfunction + +function! s:self.exit_visual() dict abort + let self._visual = 0 + return self +endfunction + +function! s:self.visual_mode() dict abort + return get(self, '_visual') +endfunction + +function! s:self.is_visual() dict abort + return get(self, '_visual') == 1 +endfunction + +function! s:self.is_line_visual() dict abort + return get(self, '_visual') == 2 +endfunction + +function! s:self.is_block_visual() dict abort + return get(self, '_visual') == 3 +endfunction + +function! s:self.visual_start_day() dict abort + return get(self, '_visual_start_day', self._day) +endfunction + +function! s:self.visual_start_time() dict abort + return get(self, '_visual_start_time', self._time) +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/pixel.vim b/bundle/calendar.vim/autoload/calendar/pixel.vim new file mode 100644 index 000000000..874e1a2f7 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel.vim @@ -0,0 +1,64 @@ +" ============================================================================= +" Filename: autoload/calendar/pixel.vim +" Author: itchyny +" License: MIT License +" Last Change: 2015/03/29 06:31:09. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +" Load the pixel files on demand. +" The pixel data are saved in files under pixel/. +" For example, the character code of 'F' is 70 so the pixel data is pixel/70. +" chr: character to get the pixel of +" returns: pixel data in an array +let s:pixel = { ' ': [ '..', '..', '..', '..', '..'] } +let s:dir = expand(':p:h') . '/pixel/' +function! calendar#pixel#get(chr) abort + if a:chr ==# '' + return repeat([''], 5) + endif + if has_key(s:pixel, a:chr) + return type(s:pixel[a:chr]) == type([]) ? s:pixel[a:chr] : s:pixel[' '] + endif + let path = s:dir . char2nr(a:chr) + if filereadable(path) + let s:pixel[a:chr] = readfile(path) + else + let s:pixel[a:chr] = 0 + endif + return get(s:pixel, a:chr, s:pixel[' ']) +endfunction + +function! calendar#pixel#len(chr) abort + let len = 0 + for c in split(a:chr, '\zs') + unlet! px + let px = calendar#pixel#get(c) + if type(px) == type([]) + let len += len(px[0]) + endif + endfor + if len(a:chr) + let len -= calendar#pixel#whitelen(a:chr[0]) + let len -= calendar#pixel#whitelen(a:chr[len(a:chr) - 1], '\.*$') + endif + return len +endfunction + +function! calendar#pixel#whitelen(chr, ...) abort + let pat = a:0 ? a:1 : '^\.*' + let px = calendar#pixel#get(a:chr) + if type(px) != type([]) + return 0 + endif + let min = 100 + for str in px + let min = min([min, len(matchstr(str, pat))]) + endfor + return min +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/pixel/100 b/bundle/calendar.vim/autoload/calendar/pixel/100 new file mode 100644 index 000000000..19249e791 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/100 @@ -0,0 +1,5 @@ +...%% +...%% +.%%%% +%%.%% +.%%%% diff --git a/bundle/calendar.vim/autoload/calendar/pixel/101 b/bundle/calendar.vim/autoload/calendar/pixel/101 new file mode 100644 index 000000000..731a29462 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/101 @@ -0,0 +1,5 @@ +..... +.%%%. +%%.%% +%%%.. +.%%%% diff --git a/bundle/calendar.vim/autoload/calendar/pixel/102 b/bundle/calendar.vim/autoload/calendar/pixel/102 new file mode 100644 index 000000000..3e1fc0919 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/102 @@ -0,0 +1,5 @@ +..%%. +.%%.. +%%%%% +.%%.. +.%%.. diff --git a/bundle/calendar.vim/autoload/calendar/pixel/103 b/bundle/calendar.vim/autoload/calendar/pixel/103 new file mode 100644 index 000000000..40513236d --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/103 @@ -0,0 +1,5 @@ +.%%%. +%%.%% +.%%%% +...%% +.%%%. diff --git a/bundle/calendar.vim/autoload/calendar/pixel/104 b/bundle/calendar.vim/autoload/calendar/pixel/104 new file mode 100644 index 000000000..288711a40 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/104 @@ -0,0 +1,5 @@ +%%... +%%... +%%%%. +%%.%% +%%.%% diff --git a/bundle/calendar.vim/autoload/calendar/pixel/105 b/bundle/calendar.vim/autoload/calendar/pixel/105 new file mode 100644 index 000000000..895db52ce --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/105 @@ -0,0 +1,5 @@ +.. +%% +.. +%% +%% diff --git a/bundle/calendar.vim/autoload/calendar/pixel/106 b/bundle/calendar.vim/autoload/calendar/pixel/106 new file mode 100644 index 000000000..da0991fcd --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/106 @@ -0,0 +1,5 @@ +...%% +..... +...%% +%%.%% +.%%%. diff --git a/bundle/calendar.vim/autoload/calendar/pixel/107 b/bundle/calendar.vim/autoload/calendar/pixel/107 new file mode 100644 index 000000000..d6564c6d0 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/107 @@ -0,0 +1,5 @@ +%%... +%%... +%%.%% +%%%%. +%%.%% diff --git a/bundle/calendar.vim/autoload/calendar/pixel/108 b/bundle/calendar.vim/autoload/calendar/pixel/108 new file mode 100644 index 000000000..fa8b61006 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/108 @@ -0,0 +1,5 @@ +%%%. +.%%. +.%%. +.%%. +.%%% diff --git a/bundle/calendar.vim/autoload/calendar/pixel/109 b/bundle/calendar.vim/autoload/calendar/pixel/109 new file mode 100644 index 000000000..d1bfc9b02 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/109 @@ -0,0 +1,5 @@ +........ +........ +%%%%%%%. +%%.%%.%% +%%.%%.%% diff --git a/bundle/calendar.vim/autoload/calendar/pixel/110 b/bundle/calendar.vim/autoload/calendar/pixel/110 new file mode 100644 index 000000000..201482391 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/110 @@ -0,0 +1,5 @@ +..... +..... +%%%%. +%%.%% +%%.%% diff --git a/bundle/calendar.vim/autoload/calendar/pixel/111 b/bundle/calendar.vim/autoload/calendar/pixel/111 new file mode 100644 index 000000000..e38468116 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/111 @@ -0,0 +1,5 @@ +..... +..... +.%%%. +%%.%% +.%%%. diff --git a/bundle/calendar.vim/autoload/calendar/pixel/112 b/bundle/calendar.vim/autoload/calendar/pixel/112 new file mode 100644 index 000000000..8eb0061c3 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/112 @@ -0,0 +1,5 @@ +%%%%. +%%.%% +%%%%. +%%... +%%... diff --git a/bundle/calendar.vim/autoload/calendar/pixel/113 b/bundle/calendar.vim/autoload/calendar/pixel/113 new file mode 100644 index 000000000..436c74194 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/113 @@ -0,0 +1,5 @@ +.%%%% +%%.%% +.%%%% +...%% +...%% diff --git a/bundle/calendar.vim/autoload/calendar/pixel/114 b/bundle/calendar.vim/autoload/calendar/pixel/114 new file mode 100644 index 000000000..f32707708 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/114 @@ -0,0 +1,5 @@ +..... +%%.%% +%%%%. +%%... +%%... diff --git a/bundle/calendar.vim/autoload/calendar/pixel/115 b/bundle/calendar.vim/autoload/calendar/pixel/115 new file mode 100644 index 000000000..feea4c5dc --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/115 @@ -0,0 +1,5 @@ +.%%%% +%%... +%%%%% +...%% +%%%%. diff --git a/bundle/calendar.vim/autoload/calendar/pixel/116 b/bundle/calendar.vim/autoload/calendar/pixel/116 new file mode 100644 index 000000000..4952c9343 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/116 @@ -0,0 +1,5 @@ +.... +.%%. +%%%% +.%%. +.%%% diff --git a/bundle/calendar.vim/autoload/calendar/pixel/117 b/bundle/calendar.vim/autoload/calendar/pixel/117 new file mode 100644 index 000000000..1ab0770c3 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/117 @@ -0,0 +1,5 @@ +..... +..... +%%.%% +%%.%% +.%%%% diff --git a/bundle/calendar.vim/autoload/calendar/pixel/118 b/bundle/calendar.vim/autoload/calendar/pixel/118 new file mode 100644 index 000000000..54676754c --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/118 @@ -0,0 +1,5 @@ +...... +...... +%%..%% +.%%%%. +..%%.. diff --git a/bundle/calendar.vim/autoload/calendar/pixel/119 b/bundle/calendar.vim/autoload/calendar/pixel/119 new file mode 100644 index 000000000..548f5a2b0 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/119 @@ -0,0 +1,5 @@ +.......... +.......... +%%..%%..%% +.%%%%%%%%. +..%%..%%.. diff --git a/bundle/calendar.vim/autoload/calendar/pixel/120 b/bundle/calendar.vim/autoload/calendar/pixel/120 new file mode 100644 index 000000000..eda334af9 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/120 @@ -0,0 +1,5 @@ +..... +..... +%%.%% +.%%%. +%%.%% diff --git a/bundle/calendar.vim/autoload/calendar/pixel/121 b/bundle/calendar.vim/autoload/calendar/pixel/121 new file mode 100644 index 000000000..a721f3fc7 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/121 @@ -0,0 +1,5 @@ +...... +%%..%% +.%%%%. +..%%.. +.%%... diff --git a/bundle/calendar.vim/autoload/calendar/pixel/122 b/bundle/calendar.vim/autoload/calendar/pixel/122 new file mode 100644 index 000000000..cd0777db8 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/122 @@ -0,0 +1,5 @@ +..... +..... +%%%%% +.%%%. +%%%%% diff --git a/bundle/calendar.vim/autoload/calendar/pixel/123 b/bundle/calendar.vim/autoload/calendar/pixel/123 new file mode 100644 index 000000000..6c347ff45 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/123 @@ -0,0 +1,5 @@ +.%%% +.%%. +%%%. +.%%. +.%%% diff --git a/bundle/calendar.vim/autoload/calendar/pixel/124 b/bundle/calendar.vim/autoload/calendar/pixel/124 new file mode 100644 index 000000000..8b347e51e --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/124 @@ -0,0 +1,5 @@ +%% +%% +%% +%% +%% diff --git a/bundle/calendar.vim/autoload/calendar/pixel/125 b/bundle/calendar.vim/autoload/calendar/pixel/125 new file mode 100644 index 000000000..471e90757 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/125 @@ -0,0 +1,5 @@ +%%%. +.%%. +.%%% +.%%. +%%%. diff --git a/bundle/calendar.vim/autoload/calendar/pixel/126 b/bundle/calendar.vim/autoload/calendar/pixel/126 new file mode 100644 index 000000000..909607e66 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/126 @@ -0,0 +1,5 @@ +....... +....... +.%%%.%% +%%.%%%. +....... diff --git a/bundle/calendar.vim/autoload/calendar/pixel/33 b/bundle/calendar.vim/autoload/calendar/pixel/33 new file mode 100644 index 000000000..133d7a47c --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/33 @@ -0,0 +1,5 @@ +%% +%% +%% +.. +%% diff --git a/bundle/calendar.vim/autoload/calendar/pixel/34 b/bundle/calendar.vim/autoload/calendar/pixel/34 new file mode 100644 index 000000000..9940c7c56 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/34 @@ -0,0 +1,5 @@ +.%%.%% +%%.%%. +...... +...... +...... diff --git a/bundle/calendar.vim/autoload/calendar/pixel/35 b/bundle/calendar.vim/autoload/calendar/pixel/35 new file mode 100644 index 000000000..cce7e7382 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/35 @@ -0,0 +1,5 @@ +.%%.%%. +%%%%%%% +.%%.%%. +%%%%%%% +.%%.%%. diff --git a/bundle/calendar.vim/autoload/calendar/pixel/36 b/bundle/calendar.vim/autoload/calendar/pixel/36 new file mode 100644 index 000000000..b2aa8dd7d --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/36 @@ -0,0 +1,6 @@ +.%%%%% +%.%%.. +%%%%%% +..%%.% +%%%%%. + diff --git a/bundle/calendar.vim/autoload/calendar/pixel/37 b/bundle/calendar.vim/autoload/calendar/pixel/37 new file mode 100644 index 000000000..8412ab577 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/37 @@ -0,0 +1,5 @@ +....%% +%%.%%. +..%%.. +.%%.%% +%%.... diff --git a/bundle/calendar.vim/autoload/calendar/pixel/38 b/bundle/calendar.vim/autoload/calendar/pixel/38 new file mode 100644 index 000000000..ea45c9f15 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/38 @@ -0,0 +1,5 @@ +..%%%.. +.%%.... +.%%%... +%%...%% +.%%%%%. diff --git a/bundle/calendar.vim/autoload/calendar/pixel/39 b/bundle/calendar.vim/autoload/calendar/pixel/39 new file mode 100644 index 000000000..a51723e9c --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/39 @@ -0,0 +1,5 @@ +.%% +%%. +... +... +... diff --git a/bundle/calendar.vim/autoload/calendar/pixel/40 b/bundle/calendar.vim/autoload/calendar/pixel/40 new file mode 100644 index 000000000..ec9b1ccac --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/40 @@ -0,0 +1,5 @@ +.%% +%%. +%%. +%%. +.%% diff --git a/bundle/calendar.vim/autoload/calendar/pixel/41 b/bundle/calendar.vim/autoload/calendar/pixel/41 new file mode 100644 index 000000000..52681cd14 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/41 @@ -0,0 +1,5 @@ +%%.. +.%%. +.%%. +.%%. +%%.. diff --git a/bundle/calendar.vim/autoload/calendar/pixel/42 b/bundle/calendar.vim/autoload/calendar/pixel/42 new file mode 100644 index 000000000..7c9582db6 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/42 @@ -0,0 +1,5 @@ +...... +%.%%.% +.%%%%. +%.%%.% +...... diff --git a/bundle/calendar.vim/autoload/calendar/pixel/43 b/bundle/calendar.vim/autoload/calendar/pixel/43 new file mode 100644 index 000000000..0f90475d1 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/43 @@ -0,0 +1,5 @@ +...... +..%%.. +%%%%%% +..%%.. +...... diff --git a/bundle/calendar.vim/autoload/calendar/pixel/44 b/bundle/calendar.vim/autoload/calendar/pixel/44 new file mode 100644 index 000000000..c570e05f5 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/44 @@ -0,0 +1,5 @@ +... +... +... +.%% +%%. diff --git a/bundle/calendar.vim/autoload/calendar/pixel/45 b/bundle/calendar.vim/autoload/calendar/pixel/45 new file mode 100644 index 000000000..06d0a5cb2 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/45 @@ -0,0 +1,5 @@ +..... +..... +%%%%% +..... +..... diff --git a/bundle/calendar.vim/autoload/calendar/pixel/46 b/bundle/calendar.vim/autoload/calendar/pixel/46 new file mode 100644 index 000000000..a24a0e6b3 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/46 @@ -0,0 +1,5 @@ +.... +.... +.... +.... +.%%. diff --git a/bundle/calendar.vim/autoload/calendar/pixel/47 b/bundle/calendar.vim/autoload/calendar/pixel/47 new file mode 100644 index 000000000..9f67e890d --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/47 @@ -0,0 +1,5 @@ +.....%%. +....%%.. +...%%... +..%%.... +.%%..... diff --git a/bundle/calendar.vim/autoload/calendar/pixel/48 b/bundle/calendar.vim/autoload/calendar/pixel/48 new file mode 100644 index 000000000..6383d29f0 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/48 @@ -0,0 +1,5 @@ +%%%%%% +%%..%% +%%..%% +%%..%% +%%%%%% diff --git a/bundle/calendar.vim/autoload/calendar/pixel/49 b/bundle/calendar.vim/autoload/calendar/pixel/49 new file mode 100644 index 000000000..7766a013d --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/49 @@ -0,0 +1,5 @@ +....%% +....%% +....%% +....%% +....%% diff --git a/bundle/calendar.vim/autoload/calendar/pixel/50 b/bundle/calendar.vim/autoload/calendar/pixel/50 new file mode 100644 index 000000000..39f9b2a86 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/50 @@ -0,0 +1,5 @@ +%%%%%% +....%% +%%%%%% +%%.... +%%%%%% diff --git a/bundle/calendar.vim/autoload/calendar/pixel/51 b/bundle/calendar.vim/autoload/calendar/pixel/51 new file mode 100644 index 000000000..40c0ca7b9 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/51 @@ -0,0 +1,5 @@ +%%%%%% +....%% +%%%%%% +....%% +%%%%%% diff --git a/bundle/calendar.vim/autoload/calendar/pixel/52 b/bundle/calendar.vim/autoload/calendar/pixel/52 new file mode 100644 index 000000000..a618e25cb --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/52 @@ -0,0 +1,5 @@ +%%..%% +%%..%% +%%%%%% +....%% +....%% diff --git a/bundle/calendar.vim/autoload/calendar/pixel/53 b/bundle/calendar.vim/autoload/calendar/pixel/53 new file mode 100644 index 000000000..86df6f758 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/53 @@ -0,0 +1,5 @@ +%%%%%% +%%.... +%%%%%% +....%% +%%%%%% diff --git a/bundle/calendar.vim/autoload/calendar/pixel/54 b/bundle/calendar.vim/autoload/calendar/pixel/54 new file mode 100644 index 000000000..0fe61e392 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/54 @@ -0,0 +1,5 @@ +%%%%%% +%%.... +%%%%%% +%%..%% +%%%%%% diff --git a/bundle/calendar.vim/autoload/calendar/pixel/55 b/bundle/calendar.vim/autoload/calendar/pixel/55 new file mode 100644 index 000000000..a33e8fce0 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/55 @@ -0,0 +1,5 @@ +%%%%%% +....%% +....%% +....%% +....%% diff --git a/bundle/calendar.vim/autoload/calendar/pixel/56 b/bundle/calendar.vim/autoload/calendar/pixel/56 new file mode 100644 index 000000000..c16f0392d --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/56 @@ -0,0 +1,5 @@ +%%%%%% +%%..%% +%%%%%% +%%..%% +%%%%%% diff --git a/bundle/calendar.vim/autoload/calendar/pixel/57 b/bundle/calendar.vim/autoload/calendar/pixel/57 new file mode 100644 index 000000000..922352e51 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/57 @@ -0,0 +1,5 @@ +%%%%%% +%%..%% +%%%%%% +....%% +%%%%%% diff --git a/bundle/calendar.vim/autoload/calendar/pixel/58 b/bundle/calendar.vim/autoload/calendar/pixel/58 new file mode 100644 index 000000000..1ffd3fff7 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/58 @@ -0,0 +1,5 @@ +.... +.%%. +.... +.%%. +.... diff --git a/bundle/calendar.vim/autoload/calendar/pixel/59 b/bundle/calendar.vim/autoload/calendar/pixel/59 new file mode 100644 index 000000000..0eab0a874 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/59 @@ -0,0 +1,5 @@ +... +.%% +... +.%% +%%. diff --git a/bundle/calendar.vim/autoload/calendar/pixel/60 b/bundle/calendar.vim/autoload/calendar/pixel/60 new file mode 100644 index 000000000..b557d3810 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/60 @@ -0,0 +1,5 @@ +...%% +.%%%. +%%... +.%%%. +...%% diff --git a/bundle/calendar.vim/autoload/calendar/pixel/61 b/bundle/calendar.vim/autoload/calendar/pixel/61 new file mode 100644 index 000000000..ca6d130f7 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/61 @@ -0,0 +1,5 @@ +..... +%%%%% +..... +%%%%% +..... diff --git a/bundle/calendar.vim/autoload/calendar/pixel/62 b/bundle/calendar.vim/autoload/calendar/pixel/62 new file mode 100644 index 000000000..91e0798b0 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/62 @@ -0,0 +1,5 @@ +%%... +.%%%. +...%% +.%%%. +%%... diff --git a/bundle/calendar.vim/autoload/calendar/pixel/63 b/bundle/calendar.vim/autoload/calendar/pixel/63 new file mode 100644 index 000000000..89c9128a6 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/63 @@ -0,0 +1,5 @@ +.%%%%. +%%..%% +...%%. +...... +..%%.. diff --git a/bundle/calendar.vim/autoload/calendar/pixel/64 b/bundle/calendar.vim/autoload/calendar/pixel/64 new file mode 100644 index 000000000..c99bc57f8 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/64 @@ -0,0 +1,5 @@ +.%%%%%%. +%%..%%%% +%%.%%.%% +%%..%%%% +.%%%%%%% diff --git a/bundle/calendar.vim/autoload/calendar/pixel/65 b/bundle/calendar.vim/autoload/calendar/pixel/65 new file mode 100644 index 000000000..40a0d27bd --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/65 @@ -0,0 +1,5 @@ +..%%.. +.%%%%. +%%..%% +%%%%%% +%%..%% diff --git a/bundle/calendar.vim/autoload/calendar/pixel/66 b/bundle/calendar.vim/autoload/calendar/pixel/66 new file mode 100644 index 000000000..b2eb2d2b0 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/66 @@ -0,0 +1,5 @@ +%%%%%. +%%..%% +%%%%%. +%%..%% +%%%%%. diff --git a/bundle/calendar.vim/autoload/calendar/pixel/67 b/bundle/calendar.vim/autoload/calendar/pixel/67 new file mode 100644 index 000000000..d30e25047 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/67 @@ -0,0 +1,5 @@ +.%%%%%. +%%...%% +%%..... +%%...%% +.%%%%%. diff --git a/bundle/calendar.vim/autoload/calendar/pixel/68 b/bundle/calendar.vim/autoload/calendar/pixel/68 new file mode 100644 index 000000000..af271d4e5 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/68 @@ -0,0 +1,5 @@ +%%%%%.. +%%..%%. +%%...%% +%%..%%. +%%%%%.. diff --git a/bundle/calendar.vim/autoload/calendar/pixel/69 b/bundle/calendar.vim/autoload/calendar/pixel/69 new file mode 100644 index 000000000..8a72c8d45 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/69 @@ -0,0 +1,5 @@ +%%%%%% +%%.... +%%%%%. +%%.... +%%%%%% diff --git a/bundle/calendar.vim/autoload/calendar/pixel/70 b/bundle/calendar.vim/autoload/calendar/pixel/70 new file mode 100644 index 000000000..f01713f83 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/70 @@ -0,0 +1,5 @@ +%%%%%% +%%.... +%%%%%. +%%.... +%%.... diff --git a/bundle/calendar.vim/autoload/calendar/pixel/71 b/bundle/calendar.vim/autoload/calendar/pixel/71 new file mode 100644 index 000000000..cb9210412 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/71 @@ -0,0 +1,5 @@ +.%%%%%. +%%...%% +%%..... +%%..%%% +.%%%.%% diff --git a/bundle/calendar.vim/autoload/calendar/pixel/72 b/bundle/calendar.vim/autoload/calendar/pixel/72 new file mode 100644 index 000000000..19ffdec73 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/72 @@ -0,0 +1,5 @@ +%%...%% +%%...%% +%%%%%%% +%%...%% +%%...%% diff --git a/bundle/calendar.vim/autoload/calendar/pixel/73 b/bundle/calendar.vim/autoload/calendar/pixel/73 new file mode 100644 index 000000000..8b347e51e --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/73 @@ -0,0 +1,5 @@ +%% +%% +%% +%% +%% diff --git a/bundle/calendar.vim/autoload/calendar/pixel/74 b/bundle/calendar.vim/autoload/calendar/pixel/74 new file mode 100644 index 000000000..577be3456 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/74 @@ -0,0 +1,5 @@ +....%% +....%% +....%% +%%..%% +.%%%%. diff --git a/bundle/calendar.vim/autoload/calendar/pixel/75 b/bundle/calendar.vim/autoload/calendar/pixel/75 new file mode 100644 index 000000000..9b8eac2fc --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/75 @@ -0,0 +1,5 @@ +%%..%% +%%.%%. +%%%%.. +%%.%%. +%%..%% diff --git a/bundle/calendar.vim/autoload/calendar/pixel/76 b/bundle/calendar.vim/autoload/calendar/pixel/76 new file mode 100644 index 000000000..cdb88b6d1 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/76 @@ -0,0 +1,5 @@ +%%.... +%%.... +%%.... +%%.... +%%%%%% diff --git a/bundle/calendar.vim/autoload/calendar/pixel/77 b/bundle/calendar.vim/autoload/calendar/pixel/77 new file mode 100644 index 000000000..179c1e50b --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/77 @@ -0,0 +1,5 @@ +%%....%% +%%%..%%% +%%%%%%%% +%%.%%.%% +%%....%% diff --git a/bundle/calendar.vim/autoload/calendar/pixel/78 b/bundle/calendar.vim/autoload/calendar/pixel/78 new file mode 100644 index 000000000..3b47ac888 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/78 @@ -0,0 +1,5 @@ +%%..%% +%%%.%% +%%%%%% +%%.%%% +%%..%% diff --git a/bundle/calendar.vim/autoload/calendar/pixel/79 b/bundle/calendar.vim/autoload/calendar/pixel/79 new file mode 100644 index 000000000..9c40d1c49 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/79 @@ -0,0 +1,5 @@ +.%%%%%. +%%...%% +%%...%% +%%...%% +.%%%%%. diff --git a/bundle/calendar.vim/autoload/calendar/pixel/80 b/bundle/calendar.vim/autoload/calendar/pixel/80 new file mode 100644 index 000000000..819866415 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/80 @@ -0,0 +1,5 @@ +%%%%%. +%%..%% +%%%%%. +%%.... +%%.... diff --git a/bundle/calendar.vim/autoload/calendar/pixel/81 b/bundle/calendar.vim/autoload/calendar/pixel/81 new file mode 100644 index 000000000..9b00eb708 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/81 @@ -0,0 +1,5 @@ +.%%%%%. +%%...%% +%%...%% +%%.%%%. +.%%%.%% diff --git a/bundle/calendar.vim/autoload/calendar/pixel/82 b/bundle/calendar.vim/autoload/calendar/pixel/82 new file mode 100644 index 000000000..0d067804c --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/82 @@ -0,0 +1,5 @@ +%%%%%%. +%%...%% +%%%%%%. +%%..%%. +%%...%% diff --git a/bundle/calendar.vim/autoload/calendar/pixel/83 b/bundle/calendar.vim/autoload/calendar/pixel/83 new file mode 100644 index 000000000..486918861 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/83 @@ -0,0 +1,5 @@ +.%%%%% +%%.... +%%%%%% +....%% +%%%%%. diff --git a/bundle/calendar.vim/autoload/calendar/pixel/84 b/bundle/calendar.vim/autoload/calendar/pixel/84 new file mode 100644 index 000000000..b9e32cbb5 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/84 @@ -0,0 +1,5 @@ +%%%%%%%% +...%%... +...%%... +...%%... +...%%... diff --git a/bundle/calendar.vim/autoload/calendar/pixel/85 b/bundle/calendar.vim/autoload/calendar/pixel/85 new file mode 100644 index 000000000..07032e3e6 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/85 @@ -0,0 +1,5 @@ +%%...%% +%%...%% +%%...%% +%%...%% +.%%%%%. diff --git a/bundle/calendar.vim/autoload/calendar/pixel/86 b/bundle/calendar.vim/autoload/calendar/pixel/86 new file mode 100644 index 000000000..c97c953dd --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/86 @@ -0,0 +1,5 @@ +%%..%% +%%..%% +%%..%% +.%%%%. +..%%.. diff --git a/bundle/calendar.vim/autoload/calendar/pixel/87 b/bundle/calendar.vim/autoload/calendar/pixel/87 new file mode 100644 index 000000000..d01e9ca28 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/87 @@ -0,0 +1,5 @@ +%%..%%..%% +%%..%%..%% +%%..%%..%% +.%%%%%%%%. +..%%..%%.. diff --git a/bundle/calendar.vim/autoload/calendar/pixel/88 b/bundle/calendar.vim/autoload/calendar/pixel/88 new file mode 100644 index 000000000..a4fdefd67 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/88 @@ -0,0 +1,5 @@ +%%..%% +.%%%%. +..%%.. +.%%%%. +%%..%% diff --git a/bundle/calendar.vim/autoload/calendar/pixel/89 b/bundle/calendar.vim/autoload/calendar/pixel/89 new file mode 100644 index 000000000..5f99346ca --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/89 @@ -0,0 +1,5 @@ +%%..%% +.%%%%. +..%%.. +..%%.. +..%%.. diff --git a/bundle/calendar.vim/autoload/calendar/pixel/90 b/bundle/calendar.vim/autoload/calendar/pixel/90 new file mode 100644 index 000000000..aa4f2e176 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/90 @@ -0,0 +1,5 @@ +%%%%%% +...%%. +..%%.. +.%%... +%%%%%% diff --git a/bundle/calendar.vim/autoload/calendar/pixel/91 b/bundle/calendar.vim/autoload/calendar/pixel/91 new file mode 100644 index 000000000..866539d11 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/91 @@ -0,0 +1,5 @@ +%%% +%%. +%%. +%%. +%%% diff --git a/bundle/calendar.vim/autoload/calendar/pixel/92 b/bundle/calendar.vim/autoload/calendar/pixel/92 new file mode 100644 index 000000000..6f52208e5 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/92 @@ -0,0 +1,5 @@ +%%.... +.%%... +..%%.. +...%%. +....%% diff --git a/bundle/calendar.vim/autoload/calendar/pixel/93 b/bundle/calendar.vim/autoload/calendar/pixel/93 new file mode 100644 index 000000000..0c67d36ac --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/93 @@ -0,0 +1,5 @@ +%%% +.%% +.%% +.%% +%%% diff --git a/bundle/calendar.vim/autoload/calendar/pixel/94 b/bundle/calendar.vim/autoload/calendar/pixel/94 new file mode 100644 index 000000000..b4fd6d12e --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/94 @@ -0,0 +1,5 @@ +..%%.. +%%..%% +...... +...... +...... diff --git a/bundle/calendar.vim/autoload/calendar/pixel/95 b/bundle/calendar.vim/autoload/calendar/pixel/95 new file mode 100644 index 000000000..dbd3d230d --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/95 @@ -0,0 +1,5 @@ +.... +.... +.... +.... +%%%% diff --git a/bundle/calendar.vim/autoload/calendar/pixel/96 b/bundle/calendar.vim/autoload/calendar/pixel/96 new file mode 100644 index 000000000..6fd45dc18 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/96 @@ -0,0 +1,5 @@ +%%.. +.%%% +.... +.... +.... diff --git a/bundle/calendar.vim/autoload/calendar/pixel/97 b/bundle/calendar.vim/autoload/calendar/pixel/97 new file mode 100644 index 000000000..1cf723e50 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/97 @@ -0,0 +1,5 @@ +........ +........ +.%%%%.%% +%%..%%%% +.%%%%.%% diff --git a/bundle/calendar.vim/autoload/calendar/pixel/98 b/bundle/calendar.vim/autoload/calendar/pixel/98 new file mode 100644 index 000000000..52398a5ac --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/98 @@ -0,0 +1,5 @@ +%%... +%%... +%%%%. +%%.%% +%%%%. diff --git a/bundle/calendar.vim/autoload/calendar/pixel/99 b/bundle/calendar.vim/autoload/calendar/pixel/99 new file mode 100644 index 000000000..f6a26a40b --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/pixel/99 @@ -0,0 +1,5 @@ +..... +..... +.%%%% +%%... +.%%%% diff --git a/bundle/calendar.vim/autoload/calendar/setlocal.vim b/bundle/calendar.vim/autoload/calendar/setlocal.vim new file mode 100644 index 000000000..ef96bcbbe --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/setlocal.vim @@ -0,0 +1,61 @@ +" ============================================================================= +" Filename: autoload/calendar/setlocal.vim +" Author: itchyny +" License: MIT License +" Last Change: 2019/07/20 13:22:17. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +" All the setlocal commands are executed using the functions in this file. + +" Set all the local settings for the current calendar buffer. +let s:undolevels = v:version > 704 || v:version == 704 && has('patch073') +let s:colorcolumn = exists('&colorcolumn') +let s:relativenumber = exists('&relativenumber') +function! calendar#setlocal#new() abort + setlocal nomodifiable buftype=nofile noswapfile readonly + \ bufhidden=hide wrap nowrap nobuflisted nofoldenable foldcolumn=0 + \ nolist completefunc= omnifunc= + \ nocursorcolumn nocursorline nomodeline + if &number + setlocal nonumber + endif + if s:undolevels + setlocal undolevels=-1 + endif + if s:colorcolumn + setlocal colorcolumn= + endif + if s:relativenumber && &relativenumber + setlocal norelativenumber + endif + call calendar#setlocal#filetype() +endfunction + +" Set modifiable so that the controller can modify the contents in the buffer. +function! calendar#setlocal#modifiable() abort + setlocal modifiable noreadonly +endfunction + +" Set nomodifiable after the controller modify the contents in the buffer. +function! calendar#setlocal#nomodifiable() abort + setlocal nomodifiable readonly +endfunction + +" Set filetype once. +function! calendar#setlocal#filetype() abort + if &l:filetype !=# 'calendar' + setlocal filetype=calendar + endif +endfunction + +" Set filetype forcibly. (see 'autocmd ColorScheme' in autocmd.vim) +function! calendar#setlocal#filetype_force() abort + setlocal filetype= + setlocal filetype=calendar +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/setting.vim b/bundle/calendar.vim/autoload/calendar/setting.vim new file mode 100644 index 000000000..be6ed45a8 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/setting.vim @@ -0,0 +1,285 @@ +" ============================================================================= +" Filename: autoload/calendar/setting.vim +" Author: itchyny +" License: MIT License +" Last Change: 2020/10/17 01:28:47. +" ============================================================================= + +scriptencoding utf-8 +let s:save_cpo = &cpo +set cpo&vim + +" Obtaining settings. +" 1: b:_calendar[option] is set by :Calendar -option=value +" 2: g:calendar_option is set in vimrc. let g:calendar_option = value +" 3: s:option() is the default value. +" Firstly, check the buffer variable if exists. It is set from argument. See +" calendar#new(args) for more detail. If the buffer was not found as a buffer +" variable, check the global variable. A user can set the variable in the vimrc +" file. Lastly, returns the default setting. All the default settings are +" defined in this file. Conversely, all the variables defined in this file can +" be configured by users from their vimrc file. +function! calendar#setting#get(name) abort + return get(get(b:, '_calendar', {}), a:name, get(g:, 'calendar_' . a:name, s:{a:name}())) +endfunction + +function! calendar#setting#get_default(name) abort + return s:{a:name}() +endfunction + +function! s:locale() abort + return substitute(v:lang, '[.-]', '_', 'g') +endfunction + +function! s:calendar() abort + return 'default' +endfunction + +function! s:calendar_candidates() abort + return 0 +endfunction + +function! s:first_day() abort + return v:lang =~# '\v(US|CA|JP|IL)|^(ja)' ? 'sunday' : 'monday' +endfunction + +let s:t = strftime('%z') +function! s:time_zone() abort + return s:t +endfunction + +function! s:date_endian() abort + return v:lang =~# '\v(JP|KR|HU|LT|IR|MN)|^(ja|zh)' ? 'big' + \ : v:lang =~# 'US' ? 'middle' + \ : 'little' +endfunction + +function! s:date_separator() abort + return v:lang =~# '\v(AM|AT|AZ|BY|BG|HR|CZ|EE|FI|GE|DE|HU|IS|KZ|KG|LV|MN|NO|RO|RU|SK|CH|TM|UA)' ? '.' + \ : v:lang =~# '\v(BD|CN|DK|FR|IN|IE|LT|NL|SE|TW)' ? '-' + \ : '/' +endfunction + +function! s:date_month_name() abort + return 0 +endfunction + +function! s:date_full_month_name() abort + return 0 +endfunction + +function! s:task() abort + return 0 +endfunction + +function! s:event_start_time() abort + return 1 +endfunction + +function! s:event_start_time_minwidth() abort + return 16 +endfunction + +function! s:week_number() abort + return 0 +endfunction + +function! s:clock_12hour() abort + return 0 +endfunction + +let s:c = expand('~/.cache/calendar.vim/') +function! s:cache_directory() abort + return s:c +endfunction + +function! s:google_calendar() abort + return 0 +endfunction + +function! s:google_task() abort + return 0 +endfunction + +function! s:updatetime() abort + return 200 +endfunction + +function! s:view() abort + return 'month' +endfunction + +function! s:views() abort + return ['year', 'month', 'week', 'day_4', 'day', 'clock'] +endfunction + +function! s:cyclic_view() abort + return 0 +endfunction + +function! s:yank_deleting() abort + return 1 +endfunction + +function! s:skip_event_delete_confirm() abort + return 0 +endfunction + +function! s:skip_task_delete_confirm() abort + return 0 +endfunction + +function! s:skip_task_clear_completed_confirm() abort + return 0 +endfunction + +function! s:task_delete() abort + return 0 +endfunction + +function! s:task_width() abort + return calendar#util#winwidth() / 6 +endfunction + +function! s:view_source() abort + return [ + \ { 'type': 'ymd' + \ , 'top': '1' + \ , 'align': 'center' + \ , 'maxwidth': 'b:calendar.view.task_visible() ? calendar#util#winwidth() - calendar#task#width() : calendar#util#winwidth() - 1' + \ , 'visible': 'b:calendar.view.get_calendar_views() !~# "clock\\|event\\|agenda"' + \ } , + \ { 'type': 'event' + \ , 'left': '(calendar#util#winwidth() - self.width()) / 2' + \ , 'top': '(calendar#util#winheight() - self.height()) / 2' + \ , 'on_top': '1' + \ , 'position': 'absolute' + \ , 'maxwidth': 'max([calendar#util#winwidth() / 3, 15])' + \ , 'maxheight': 'max([calendar#util#winheight() / 2, 3])' + \ , 'visible': 'b:calendar.view.event_visible() && b:calendar.view.get_calendar_views() !~# "clock\\|event\\|agenda"' + \ }, + \ { 'type': 'task' + \ , 'align': 'right' + \ , 'left': 'calendar#util#winwidth() - calendar#task#width()' + \ , 'top': '(calendar#util#winheight() - self.height()) / 2' + \ , 'position': 'absolute' + \ , 'maxwidth': 'calendar#task#width()' + \ , 'maxheight': 'max([calendar#util#winheight() * 5 / 6, 3])' + \ , 'visible': 'b:calendar.view.task_visible()' + \ }, + \ { 'type': 'help' + \ , 'align': 'center' + \ , 'position': 'absolute' + \ , 'on_top': '1' + \ , 'left': '(calendar#util#winwidth() - self.width()) / 2' + \ , 'top': '(calendar#util#winheight() - self.height()) / 2' + \ , 'maxwidth': 'max([min([calendar#util#winwidth() / 2, min([77, calendar#util#winwidth()])]), min([30, calendar#util#winwidth()])])' + \ , 'maxheight': 'max([calendar#util#winheight() * 3 / 5, 3])' + \ , 'visible': 'b:calendar.view.help_visible()' + \ }, + \ { 'type': 'calendar' + \ , 'top': 'b:calendar.view.get_calendar_views() =~# "clock\\|event\\|agenda" ? 0 : 3' + \ , 'align': 'center' + \ , 'maxwidth': 'b:calendar.view.task_visible() ? calendar#util#winwidth() - calendar#task#width() - 3 : calendar#util#winwidth() - 1' + \ , 'maxheight': 'calendar#util#winheight() - (b:calendar.view.get_calendar_views() =~# "clock\\|event\\|agenda" ? 0 : 3)' + \ }, + \ ] +endfunction + +function! calendar#setting#frame() abort + let n = calendar#setting#get('frame') + if has_key(s:f, n) | return s:f[n] | endif + let s:f[n] = calendar#setting#get('frame_' . n) + return s:f[n] +endfunction +let s:f = {} + +function! s:frame() abort + return &enc ==# 'utf-8' && &fenc ==# 'utf-8' ? 'unicode' : 'default' +endfunction + +function! s:frame_default() abort + return { 'type': 'default', 'vertical': '|', 'horizontal': '-', 'junction': '+', + \ 'left': '+', 'right': '+', 'top': '+', 'bottom': '+', + \ 'topleft': '+', 'topright': '+', 'bottomleft': '+', 'bottomright': '+' } +endfunction + +function! s:frame_unicode() abort + if &enc ==# 'utf-8' && &fenc ==# 'utf-8' + return { 'type': 'unicode', 'vertical': "\u2502", 'horizontal': "\u2500", 'junction': "\u253C", + \ 'left': "\u251C", 'right': "\u2524", 'top': "\u252C", 'bottom': "\u2534", + \ 'topleft': "\u250C", 'topright': "\u2510", 'bottomleft': "\u2514", 'bottomright': "\u2518" } + else + return s:frame_default() + endif +endfunction + +function! s:frame_unicode_bold() abort + if &enc ==# 'utf-8' && &fenc ==# 'utf-8' + return { 'type': 'unicode_bold', 'vertical': "\u2503", 'horizontal': "\u2501", 'junction': "\u254B", + \ 'left': "\u2523", 'right': "\u252B", 'top': "\u2533", 'bottom': "\u253B", + \ 'topleft': "\u250F", 'topright': "\u2513", 'bottomleft': "\u2517", 'bottomright': "\u251B" } + else + return s:frame_default() + endif +endfunction + +function! s:frame_unicode_round() abort + if &enc ==# 'utf-8' && &fenc ==# 'utf-8' + return extend(s:frame_unicode_bold(), { + \ 'type': 'unicode_round', 'topleft': "\u256D", 'topright': "\u256E", + \ 'bottomleft': "\u2570", 'bottomright': "\u256F" }) + else + return s:frame_default() + endif +endfunction + +function! s:frame_unicode_double() abort + if &enc ==# 'utf-8' && &fenc ==# 'utf-8' + return { 'type': 'unicode_double', 'vertical': "\u2551", 'horizontal': "\u2550", 'junction': "\u256C", + \ 'left': "\u2560", 'right': "\u2563", 'top': "\u2566", 'bottom': "\u2569", + \ 'topleft': "\u2554", 'topright': "\u2557", 'bottomleft': "\u255A", 'bottomright': "\u255D" } + else + return s:frame_default() + endif +endfunction + +function! s:frame_space() abort + return { 'type': 'space', 'vertical': ' ', 'horizontal': ' ', 'junction': ' ', + \ 'left': ' ', 'right': ' ', 'top': ' ', 'bottom': ' ', + \ 'topleft': ' ', 'topright': ' ', 'bottomleft': ' ', 'bottomright': ' ' } +endfunction + +function! s:google_client() abort + if has_key(s:, '_google_client') + return s:_google_client + endif + let s:_google_client = { + \ 'redirect_uri': 'urn:ietf:wg:oauth:2.0:oob', + \ 'scope': 'https://www.googleapis.com/auth/calendar https://www.googleapis.com/auth/tasks', + \ 'api_key': '', + \ 'client_id': '', + \ 'client_secret': '', + \ } + if exists('g:calendar_google_api_key') + let s:_google_client.api_key = g:calendar_google_api_key + endif + if exists('g:calendar_google_client_id') + let s:_google_client.client_id = g:calendar_google_client_id + endif + if exists('g:calendar_google_client_secret') + let s:_google_client.client_secret = g:calendar_google_client_secret + endif + return s:_google_client +endfunction + +function! s:message_prefix() abort + return '[calendar] ' +endfunction + +function! s:debug() abort + return 0 +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/string.vim b/bundle/calendar.vim/autoload/calendar/string.vim new file mode 100644 index 000000000..9d311cb1b --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/string.vim @@ -0,0 +1,80 @@ +" ============================================================================= +" Filename: autoload/calendar/string.vim +" Author: itchyny +" License: MIT License +" Last Change: 2016/11/06 12:00:00. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +" String manipulations. +" All the functions were imported from vital.vim. +" https://github.com/vim-jp/vital.vim (Public Domain) + +let s:cache = calendar#countcache#new('string.vim') + +function! calendar#string#truncate(str, width) abort + let key = a:width . 'C' . a:str + if s:cache.has_key(key) | return s:cache.get(key) | endif + if a:str =~# '^[\x20-\x7e]*$' + return len(a:str) < a:width + \ ? printf('%-' . a:width . 's', a:str) + \ : strpart(a:str, 0, a:width) + endif + let ret = a:str + let width = strdisplaywidth(a:str) + if width > a:width + let ret = calendar#string#strwidthpart(ret, a:width) + let width = strdisplaywidth(ret) + endif + if width < a:width + let ret .= repeat(' ', a:width - width) + endif + return s:cache.save(key, ret) +endfunction + +function! calendar#string#truncate_reverse(str, width) abort + let key = a:width . 'U' . a:str + if s:cache.has_key(key) | return s:cache.get(key) | endif + if a:str =~# '^[\x20-\x7e]*$' + return len(a:str) < a:width + \ ? printf('%-' . a:width . 's', a:str) + \ : strpart(a:str, len(a:str) - a:width) + endif + let ret = a:str + let width = strdisplaywidth(a:str) + if width > a:width + let ret = calendar#string#strwidthpart_reverse(ret, a:width) + let width = strdisplaywidth(ret) + endif + if width < a:width + let ret = repeat(' ', a:width - width) . ret + endif + return s:cache.save(key, ret) +endfunction + +function! calendar#string#strdisplaywidth(str) abort + return strdisplaywidth(a:str) +endfunction + +function! calendar#string#strwidthpart(str, width) abort + let key = a:width . 'T' . a:str + if s:cache.has_key(key) | return s:cache.get(key) | endif + let str = tr(a:str, "\t", ' ') + let vcol = a:width + 2 + let ret = matchstr(str, '.*\%<' . (vcol < 0 ? 0 : vcol) . 'v') + return s:cache.save(key, ret) +endfunction + +function! calendar#string#strwidthpart_reverse(str, width) abort + let key = a:width . 'R' . a:str + if s:cache.has_key(key) | return s:cache.get(key) | endif + let str = tr(a:str, "\t", ' ') + let vcol = strdisplaywidth(str) - a:width + let ret = matchstr(str, '\%>' . (vcol < 0 ? 0 : vcol) . 'v.*') + return s:cache.save(key, ret) +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/task.vim b/bundle/calendar.vim/autoload/calendar/task.vim new file mode 100644 index 000000000..93f8f4f88 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/task.vim @@ -0,0 +1,92 @@ +" ============================================================================= +" Filename: autoload/calendar/task.vim +" Author: itchyny +" License: MIT License +" Last Change: 2020/07/21 00:14:40. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +" Task controller. +" This object handles both local task and Google Task. +function! calendar#task#new() abort + let self = copy(s:self) + if calendar#setting#get('google_task') + let self.task_source_name = 'google' + else + let self.task_source_name = 'local' + endif + let self.task_source = calendar#task#{self.task_source_name}#new() + return self +endfunction + +let s:self = {} + +let s:self._updated = 0 + +function! s:self.updated() dict abort + return [self._updated] +endfunction + +function! s:self.clear_cache() dict abort + let self._updated = 1 +endfunction + +function! s:self.get_taskList() dict abort + return self.task_source.get_taskList() +endfunction + +function! s:self.get_task() dict abort + if self._updated || !has_key(self, 'task') + let self.task = self.task_source.get_task() + endif + let self._updated = 0 + return self.task +endfunction + +function! s:self.insert(listid, previous, parent, title, ...) dict abort + let self._updated = 1 + call self.task_source.insert(a:listid, a:previous, a:parent, a:title, a:0 ? a:1 : {}) +endfunction + +function! s:self.move(listid, taskid, previous, parent) dict abort + let self._updated = 1 + call self.task_source.move(a:listid, a:taskid, a:previous, a:parent) +endfunction + +function! s:self.update(listid, taskid, title, ...) dict abort + let self._updated = 1 + call self.task_source.update(a:listid, a:taskid, a:title, a:0 ? a:1 : {}) +endfunction + +function! s:self.complete(listid, taskid) dict abort + let self._updated = 1 + call self.task_source.complete(a:listid, a:taskid) +endfunction + +function! s:self.uncomplete(listid, taskid) dict abort + let self._updated = 1 + call self.task_source.uncomplete(a:listid, a:taskid) +endfunction + +function! s:self.clear_completed(listid) dict abort + let self._updated = 1 + call self.task_source.clear_completed(a:listid) +endfunction + +function! s:self.delete(listid, taskid) dict abort + let self._updated = 1 + call self.task_source.delete(a:listid, a:taskid) +endfunction + +function! calendar#task#width() abort + let frame = calendar#setting#frame() + return min([ + \ max([calendar#setting#get("task_width"), 10]) + \ + strdisplaywidth(frame.left) + strdisplaywidth(frame.right) + 2, + \ calendar#util#winwidth()]) +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/task/google.vim b/bundle/calendar.vim/autoload/calendar/task/google.vim new file mode 100644 index 000000000..6b65de4ca --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/task/google.vim @@ -0,0 +1,54 @@ +" ============================================================================= +" Filename: autoload/calendar/task/google.vim +" Author: itchyny +" License: MIT License +" Last Change: 2020/07/21 00:15:11. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +function! calendar#task#google#new() abort + return deepcopy(s:self) +endfunction + +let s:self = {} + +function! s:self.get_taskList() dict abort + return calendar#google#task#getTaskList() +endfunction + +function! s:self.get_task() dict abort + return calendar#google#task#getTasks() +endfunction + +function! s:self.insert(listid, previous, parent, title, ...) dict abort + call calendar#google#task#insert(a:listid, a:previous, a:parent, a:title, a:0 ? a:1 : {}) +endfunction + +function! s:self.move(listid, taskid, previous, parent) dict abort + call calendar#google#task#move(a:listid, a:taskid, a:previous, a:parent) +endfunction + +function! s:self.update(listid, taskid, title, ...) dict abort + call calendar#google#task#update(a:listid, a:taskid, a:title, a:0 ? a:1 : {}) +endfunction + +function! s:self.complete(listid, taskid) dict abort + call calendar#google#task#complete(a:listid, a:taskid) +endfunction + +function! s:self.uncomplete(listid, taskid) dict abort + call calendar#google#task#uncomplete(a:listid, a:taskid) +endfunction + +function! s:self.clear_completed(listid) dict abort + call calendar#google#task#clear_completed(a:listid) +endfunction + +function! s:self.delete(listid, taskid) dict abort + call calendar#google#task#delete(a:listid, a:taskid) +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/task/local.vim b/bundle/calendar.vim/autoload/calendar/task/local.vim new file mode 100644 index 000000000..a890a64e9 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/task/local.vim @@ -0,0 +1,184 @@ +" ============================================================================= +" Filename: autoload/calendar/task/local.vim +" Author: itchyny +" License: MIT License +" Last Change: 2020/11/19 07:41:02. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +function! calendar#task#local#new() abort + return deepcopy(s:self) +endfunction + +let s:cache = calendar#cache#new('local') + +let s:task_cache = s:cache.new('task') + +let s:self = {} + +function! s:self.get_taskList() dict abort + if has_key(self, 'localtasklist') + return self.localtasklist + else + let taskList = s:cache.get('taskList') + if type(taskList) == type({}) && has_key(taskList, 'items') && type(taskList.items) == type([]) + let self.localtasklist = taskList + else + let self.localtasklist = { 'items': [{'id': calendar#util#id(), 'title': get(calendar#message#get('task'), 'title', 'Task')}] } + call s:cache.save('taskList', self.localtasklist) + endif + endif + return self.localtasklist +endfunction + +function! s:self.get_task() dict abort + let taskList = self.get_taskList() + let task = [] + if has_key(taskList, 'items') && type(taskList.items) == type([]) + for item in taskList.items + call add(task, item) + let task[-1].items = [] + unlet! cnt + let cnt = s:task_cache.new(item.id).get('information') + if type(cnt) == type({}) && cnt != {} + let i = 0 + while type(cnt) == type({}) + unlet! cnt + let cnt = s:task_cache.new(item.id).get(i) + if type(cnt) == type({}) && cnt != {} && has_key(cnt, 'items') && type(cnt.items) == type([]) + call extend(task[-1].items, cnt.items) + endif + let i += 1 + endwhile + endif + endfor + endif + let self.localtask = task + return task +endfunction + +function! s:self.insert(listid, previous, parent, title, ...) dict abort + let k = self.get_tasklist_index(a:listid) + if k >= 0 + let j = self.get_index(k, a:previous) + 1 + call insert(self.localtask[k].items, { 'title': a:title, 'id': calendar#util#id() }, j) + call self.save() + endif +endfunction + +function! s:self.move(listid, taskid, previous, parent) dict abort + let k = self.get_tasklist_index(a:listid) + if k >= 0 + let j = self.get_index(k, a:taskid) + let pj = a:previous ==# '' ? 0 : self.get_index(k, a:previous) + if j >= 0 && pj >= 0 + let task = deepcopy(self.localtask[k].items[j]) + call remove(self.localtask[k].items, j) + let pj = a:previous ==# '' ? -1 : self.get_index(k, a:previous) + call insert(self.localtask[k].items, task, pj + 1) + call self.save() + endif + endif +endfunction + +function! s:self.update(listid, taskid, title, ...) dict abort + let k = self.get_tasklist_index(a:listid) + if k >= 0 + let j = self.get_index(k, a:taskid) + if j >= 0 + call extend(self.localtask[k].items[j], { 'title': a:title }) + call self.save() + endif + endif +endfunction + +function! s:self.complete(listid, taskid) dict abort + let k = self.get_tasklist_index(a:listid) + if k >= 0 + let j = self.get_index(k, a:taskid) + if j >= 0 + call extend(self.localtask[0].items[j], { 'status': 'completed' }) + call self.save() + endif + endif +endfunction + +function! s:self.uncomplete(listid, taskid) dict abort + let k = self.get_tasklist_index(a:listid) + if k >= 0 + let j = self.get_index(k, a:taskid) + if j >= 0 + if has_key(self.localtask[0].items[j], 'status') + call remove(self.localtask[0].items[j], 'status') + endif + call self.save() + endif + endif +endfunction + +function! s:self.clear_completed(listid) dict abort + if has_key(self, 'localtask') + for task in self.localtask + call filter(task.items, 'get(v:val, "status", "") !=# "completed"') + endfor + call self.save() + endif +endfunction + +function! s:self.delete(listid, taskid) dict abort + let k = self.get_tasklist_index(a:listid) + if k >= 0 + let j = self.get_index(k, a:taskid) + if j >= 0 + call remove(self.localtask[0].items, j) + call self.save() + endif + endif +endfunction + +function! s:self.save() dict abort + if has_key(self, 'localtask') + for task in self.localtask + call s:task_cache.new(task.id).save(0, task) + call s:task_cache.new(task.id).save('information', { 'id': task.id, 'title': task.title }) + endfor + endif +endfunction + +function! s:self.get_tasklist_index(id) dict abort + if has_key(self, 'localtask') + let j = -1 + for i in range(len(self.localtask)) + if self.localtask[i].id ==# a:id + let j = i + break + endif + endfor + if j < 0 && len(self.localtask) + return 0 + endif + return j + endif + return -1 +endfunction + +function! s:self.get_index(listindex, id) dict abort + if has_key(self, 'localtask') + if 0 <= a:listindex && a:listindex < len(self.localtask) + let j = -1 + for i in range(len(self.localtask[a:listindex].items)) + if self.localtask[0].items[i].id ==# a:id + let j = i + break + endif + endfor + return j + endif + endif + return -1 +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/text.vim b/bundle/calendar.vim/autoload/calendar/text.vim new file mode 100644 index 000000000..73b6bece4 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/text.vim @@ -0,0 +1,155 @@ +" ============================================================================= +" Filename: autoload/calendar/text.vim +" Author: itchyny +" License: MIT License +" Last Change: 2015/03/29 06:32:06. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +" Text object, string with a position to display, and syntaxes. +" s: The string (if it is a string) or the length of spaces (if it is a number) +" x: Position x +" y: Position y +" syn: The syntax string (For example, Sunday, Saturday and Cursor) +fu! calendar#text#new(s, x, y, syn) abort + retu extend(copy(s:self),{'s':a:s,'x':a:x,'y':a:y,'t':!type(a:s),'syn':[[a:syn,a:y,a:x,a:x+(type(a:s)?len(a:s):a:s),0]]}) +endfu + +let s:self = {} + +" Move all the things. +fu! s:self.move(x, y) dict abort + let self.x += a:x + let self.y += a:y + cal map(self.syn, '[v:val[0],v:val[1]+a:y,v:val[2]+a:x,v:val[3]+a:x,v:val[4]]') + retu self +endfu + +" Extend the syntaxes. +fu! s:self.height(h) dict abort + for s in self.syn + if a:h + let s[4] = a:h + en + endfo + retu self +endfu + +" Split all the extend the syntaxes. +fu! s:self.split() dict abort + let syn = [] + for s in self.syn + if s[4] + let t = s + let l = s[4] + let s[4] = 0 + wh l > 1 + let t = copy(t) + let t[1] += 1 + cal add(syn, t) + let l -= 1 + endw + en + endfo + retu map(syn, 'calendar#text#new(v:val[3] - v:val[2], v:val[2], v:val[1], v:val[0])') +endfu + +" :h version7 | /7.2.061 +silent! call calendar#string#strdisplaywidth('') + +let s:W = function((exists('*strdisplaywidth') ? '' : 'calendar#string#') . 'strdisplaywidth') +let s:T = function('calendar#string#truncate') +let s:R = function('calendar#string#truncate_reverse') + +fu! s:self.concat(t) dict abort + let s = self.syn + let t = a:t.syn + let q = range(len(s)) + let l = s:T(self.s, a:t.x) + let r = s:R(self.s, s:W(self.s) - s:W(a:t.s) - a:t.x) + let x = len(l) - a:t.x + let e = len(l) + len(a:t.s) + let f = len(self.s) - len(r) + let y = min([e, f]) + let m = e - f + if !a:t.t + let self.s = l . a:t.s . r + en + if x + cal s:shift(t, x) + en + for i in q + if s[i][2] >= y | let s[i][2] += m | en + if s[i][3] >= y | let s[i][3] += m | en + endfo + retu x +endfu + +fu! s:shift(t, x) abort + let p = range(len(a:t)) + for i in p + let a:t[i][2] += a:x + let a:t[i][3] += a:x + endfo +endfu + +fu! s:over(j, v, u) abort + let [s, d] = [[], []] + let v = a:v + let u = a:u + if u[2] < v[2] + if u[3] <= v[3] + let u[3] = v[2] + el + let syn = copy(u) + let u[3] = v[2] + let syn[2] = v[3] + cal add(s, syn) + en + el + if u[3] <= v[3] + cal add(d, a:j) + el + let u[2] = v[3] + en + en + retu [s, d] +endfu + +" Text piling, the most important method of text object. +fu! s:self.over(t) dict abort + let s = self.syn + let t = a:t.syn + let x = a:t.t ? 0 : self.concat(a:t) + if len(s) == 1 && s[0][0] == '' + let self.syn = t + retu x + en + let p = range(len(t)) + for i in p + let d = [] + for j in range(len(s)) + if s[j][3] <= t[i][2] + con + elsei s[j][2] >= t[i][3] + con + elsei t[i][0] != 'Cursor' && s[j][0] != 'Cursor' + let [b, c] = s:over(j, t[i], s[j]) + cal extend(s, b) + cal extend(d, c) + en + endfo + if len(d) + for n in reverse(d) + cal remove(s, n) + endfo + en + endfo + cal extend(s, t) + retu x +endfu + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/time.vim b/bundle/calendar.vim/autoload/calendar/time.vim new file mode 100644 index 000000000..78d26dafb --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/time.vim @@ -0,0 +1,241 @@ +" ============================================================================= +" Filename: autoload/calendar/time.vim +" Author: itchyny +" License: MIT License +" Last Change: 2017/05/08 07:45:01. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +" Time object +" h: hour +" m: minute +" s: second +function! calendar#time#new(h, m, s) abort + return extend(copy(s:self), { 'h': a:h, 'm': a:m, 's': a:s }) +endfunction + +if exists('*strftime') + function! calendar#time#now() abort + return calendar#time#new(strftime('%H') * 1, strftime('%M') * 1, strftime('%S') * 1) + endfunction +else + function! calendar#time#now() abort + return calendar#time#new(system('date "+%H"') * 1, system('date "+%M"') * 1, system('date "+%S"') * 1) + endfunction +endif + +function! calendar#time#hour12(h) abort + return a:h == 0 ? 12 : a:h < 13 ? a:h : a:h - 12 +endfunction + +let s:time_zone_cache = {} +function! calendar#time#time_zone() abort + let time_zone = calendar#setting#get('time_zone') + if has_key(s:time_zone_cache, time_zone) + return s:time_zone_cache[time_zone] + endif + if time_zone ==# '' + return 0 + endif + let str = time_zone + let sign_str = str[0] ==# '-' ? '-' : str[0] ==# '+' ? '+' : '' + let str = str[len(sign_str):] + let d = matchstr(str, '^\d\+') + let str = str[len(d):] + let [ h, m, s ] = [ 0, 0, 0 ] + let onlyhour = 0 + if len(d) == 1 || len(d) == 2 + let h = d + 0 + let onlyhour = 1 + elseif len(d) == 3 + let h = d[0] + 0 + let m = d[1:] + 0 + elseif len(d) == 4 + let h = d[:1] + 0 + let m = d[2:] + 0 + elseif len(d) >= 5 + let h = d[:1] + 0 + let m = d[2:] + 0 + let s = d[4:] + 0 + endif + let str = substitute(str, '^[^[:digit:]]\+', '', 'g') + let d = matchstr(str, '^\d\+') + let str = str[len(d):] + if len(d) == 1 || len(d) == 2 + if onlyhour + let m = d + 0 + else + let s = d + 0 + endif + elseif len(d) == 3 + if onlyhour + let m = d[0] + 0 + let s = d[1:] + 0 + else + let s = d + 0 + endif + elseif len(d) == 4 + if onlyhour + let m = d[:1] + 0 + let s = d[2:] + 0 + else + let s = d + 0 + endif + endif + let str = substitute(str, '^[^[:digit:]]\+', '', 'g') + let d = matchstr(str, '^\d\+') + if len(d) + let s = d + 0 + endif + let s:time_zone_cache[time_zone] = (sign_str ==# '-' ? -1 : 1) * (((h * 60) + m) * 60 + s) + return s:time_zone_cache[time_zone] +endfunction + +let s:time_cache = {} +function! calendar#time#parse(str) abort + if a:str ==# '' + return 0 + endif + if has_key(s:time_cache, a:str) + return s:time_cache[a:str] + endif + let [ h, m, s ] = [ 0, 0, 0 ] + let timestr = matchstr(a:str, '^\d\+:\d\+\%(:\d\+\)\?') + let str = a:str[len(timestr):] + let hms = map(split(timestr, ':'), 'v:val + 0') + if len(hms) == 3 + let [ h, m, s ] = hms + elseif len(hms) == 2 + let [ h, m ] = hms + endif + let time = ((h * 60) + m) * 60 + s + if str ==? 'Z' + let s:time_cache[a:str] = time + return s:time_cache[a:str] + endif + if str ==# '' + let s:time_cache[a:str] = time - calendar#time#time_zone() + return s:time_cache[a:str] + endif + if has_key(s:time_cache, str) + let [ dh, dm, ds ] = s:time_cache[str] + else + let [ dh, dm, ds ] = [ 0, 0, 0 ] + let timestr = matchstr(str, '-\?\d\+:\d\+\%(:\d\+\)\?') + let hms = map(split(timestr, ':'), 'v:val + 0') + if len(hms) == 3 + let [ dh, dm, ds ] = hms + elseif len(hms) == 2 + let [ dh, dm ] = hms + endif + let s:time_cache[str] = [ dh, dm, ds ] + endif + let s:time_cache[a:str] = time - (((dh * 60) + dm) * 60 + ds) + return s:time_cache[a:str] +endfunction + +let s:datetime_cache = {} +function! calendar#time#datetime(str) abort + let time_zone = calendar#time#time_zone() + let key = a:str . ',' . time_zone + if has_key(s:datetime_cache, key) + return s:datetime_cache[key] + endif + let time = a:str =~# 'T' ? calendar#time#parse(matchstr(a:str, 'T\zs.*')) + time_zone : 0 + let ymd = map(split(matchstr(a:str, '\d\+-\d\+-\d\+'), '-'), 'v:val + 0') + if len(ymd) != 3 + return [] + endif + let [ y, m, d ] = ymd + let min = s:div(time, 60) + let sec = time - 60 * min + let hour = s:div(min, 60) + let min -= 60 * hour + let day = s:div(hour, 24) + let hour -= 24 * day + if day != 0 + let [ y, m, d ] = calendar#day#new(y, m, d).add(day).get_ymd() + endif + let s:datetime_cache[key] = [ y, m, d, hour, min, sec ] + return s:datetime_cache[key] +endfunction + +let s:self = {} + +function! s:div(x, y) abort + return a:x/a:y-((a:x<0)&&(a:x%a:y)) +endfunction + +function! s:self.new(h, m, s) dict abort + return calendar#time#new(a:h, a:m, a:s) +endfunction + +function! s:self.get_hms() dict abort + return [self.h, self.m, self.s] +endfunction + +function! s:self.add_hour(diff) dict abort + let [h, m, s] = self.get_hms() + let d = 0 + let h += a:diff + let d += s:div(h, 24) + let h -= 24 * s:div(h, 24) + return [d, self.new(h, m, s)] +endfunction + +function! s:self.add_minute(diff) dict abort + let [h, m, s] = self.get_hms() + let d = 0 + let m += a:diff + let h += s:div(m, 60) + let m -= 60 * s:div(m, 60) + let d += s:div(h, 24) + let h -= 24 * s:div(h, 24) + return [d, self.new(h, m, s)] +endfunction + +function! s:self.add_second(diff) dict abort + let [h, m, s] = self.get_hms() + let d = 0 + let s += a:diff + let m += s:div(s, 60) + let s -= 60 * s:div(s, 60) + let h += s:div(m, 60) + let m -= 60 * s:div(m, 60) + let d += s:div(h, 24) + let h -= 24 * s:div(h, 24) + return [d, self.new(h, m, s)] +endfunction + +function! s:self.second() dict abort + return self.get_hms()[2] +endfunction + +function! s:self.minute() dict abort + return self.get_hms()[1] +endfunction + +function! s:self.hour() dict abort + return self.get_hms()[0] +endfunction + +function! s:self.seconds() dict abort + return (self.hour() * 60 + self.minute()) * 60 + self.second() +endfunction + +function! s:self.add(time) dict abort + return self.add_second(a:time.seconds()) +endfunction + +function! s:self.subtract(time) dict abort + return self.add_second(-a:time.seconds()) +endfunction + +function! s:self.sub(time) dict abort + return self.seconds() - a:time.seconds() +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/timestamp.vim b/bundle/calendar.vim/autoload/calendar/timestamp.vim new file mode 100644 index 000000000..9c422301e --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/timestamp.vim @@ -0,0 +1,42 @@ +" ============================================================================= +" Filename: autoload/calendar/timestamp.vim +" Author: itchyny +" License: MIT License +" Last Change: 2020/11/19 07:41:09. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +" Save time stamps, not so that too many downloading requests occurs. +" This is used in google/task.vim and google/calendar.vim. + +let s:cache = calendar#cache#new('timestamp') + +function! calendar#timestamp#update(name, sec) abort + let cache = s:cache.get(a:name) + if type(cache) == type({}) + \ && has_key(cache, 'name') && cache.name ==# a:name + \ && has_key(cache, 'day') && type(cache.day) == type([]) && len(cache.day) == 3 + \ && has_key(cache, 'time') && type(cache.time) == type([]) && len(cache.time) == 3 + let daydiff = calendar#day#today().sub(call('calendar#day#new', cache.day)) + let timediff = calendar#time#now().sub(call('calendar#time#new', cache.time)) + let refresh = timediff + daydiff * 86400 >= a:sec + else + let refresh = 1 + endif + if refresh + call s:cache.save(a:name, + \ { 'name': a:name + \ , 'day' : calendar#day#today().get_ymd() + \ , 'time': calendar#time#now().get_hms() }) + endif + return refresh +endfunction + +function! calendar#timestamp#clear() abort + call s:cache.clear() +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/util.vim b/bundle/calendar.vim/autoload/calendar/util.vim new file mode 100644 index 000000000..97e9ab4fd --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/util.vim @@ -0,0 +1,117 @@ +" ============================================================================= +" Filename: autoload/calendar/util.vim +" Author: itchyny +" License: MIT License +" Last Change: 2019/07/30 22:37:39. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +" Utility functions. + +" Version of this application. +function! calendar#util#version() abort + return '0.0' +endfunction + +" Name of this application. +function! calendar#util#name() abort + return 'calendar.vim' +endfunction + +" License of this application. +function! calendar#util#license() abort + return 'MIT License' +endfunction + +" Name of the author. +function! calendar#util#author() abort + return 'itchyny (https://github.com/itchyny)' +endfunction + +" Repository URL. +function! calendar#util#repository() abort + return 'https://github.com/itchyny/calendar.vim' +endfunction + +" Bug tracker URL. +function! calendar#util#issue() abort + return 'https://github.com/itchyny/calendar.vim/issues' +endfunction + +" winwidth +" Take the minimum width if the calendar buffer is displayed in multiple +" windows. For example, a calendar is viewed on a vertically splitted window +" and execute top new. +function! calendar#util#winwidth() abort + return min(map(filter(range(1,winnr('$')),'winbufnr(v:val)==winbufnr(0)'),'winwidth(v:val)'))-1 +endfunction + +" winheight +" Take the minimum height. +function! calendar#util#winheight() abort + return min(map(filter(range(1,winnr('$')),'winbufnr(v:val)==winbufnr(0)'),'winheight(v:val)')) +endfunction + +" Used for the return value of cnoremap. +function! calendar#util#update_keys() abort + silent! call histadd(':', getcmdline()) + return "\\silent call b:calendar.update()\" +endfunction + +" Get the command line, substituting the leading colons. +function! calendar#util#getcmdline() abort + return substitute(getcmdline(), '^\(\s*:\)*\s*', '', '') +endfunction + +" Yank text +function! calendar#util#yank(text) abort + let @" = a:text + if has('clipboard') || has('xterm_clipboard') + let @+ = a:text + endif +endfunction + +" Id generator +let s:id = 0 +function! calendar#util#id() abort + let [y, m, d] = calendar#day#today().get_ymd() + let [h, i, s] = calendar#time#now().get_hms() + let s:id = (s:id + 1) % 10000 + return printf('%04d%02d%02d%02d%02d%02d%04d', y, m, d, h, i, s, s:id) +endfunction + +" Execute shell command. +function! calendar#util#system(cmd) abort + silent! return system(a:cmd) +endfunction + +" Remove directory. +if has('unix') + function! calendar#util#rmdir(path, ...) abort + let flags = a:0 ? a:1 : '' + let cmd = flags =~# 'r' ? 'rm -r' : 'rmdir' + let cmd .= flags =~# 'f' && cmd ==# 'rm -r' ? ' -f' : '' + let ret = system(cmd . ' ' . shellescape(a:path)) + endfunction +elseif has('win32') + function! calendar#util#rmdir(path, ...) abort + let flags = a:0 ? a:1 : '' + if &shell =~? 'sh$' + let cmd = flags =~# 'r' ? 'rm -r' : 'rmdir' + let cmd .= flags =~# 'f' && cmd ==# 'rm -r' ? ' -f' : '' + let ret = system(cmd . ' ' . shellescape(a:path)) + else + let cmd = 'rmdir /Q' + let cmd .= flags =~# 'r' ? ' /S' : '' + let ret = system(cmd . ' "' . a:path . '"') + endif + endfunction +else + function! calendar#util#rmdir(path, ...) abort + endfunction +endif + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/view.vim b/bundle/calendar.vim/autoload/calendar/view.vim new file mode 100644 index 000000000..fcf6ce20a --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/view.vim @@ -0,0 +1,466 @@ +" ============================================================================= +" Filename: autoload/calendar/view.vim +" Author: itchyny +" License: MIT License +" Last Change: 2019/08/07 21:22:19. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +function! calendar#view#new() abort + let self = copy(s:self) + call self.set_view_source(calendar#setting#get('view_source')) + call self.set_calendar_views(calendar#setting#get('views')) + call self.set_index(calendar#setting#get('view')) + call self.set_task_visibility(calendar#setting#get('task')) + return self +endfunction + +let s:self = {} + +let s:self.index = 0 +let s:self.calendar_views = ['year', 'month', 'week', 'day_4', 'day_1', 'clock'] +let s:self.index_max = len(s:self.calendar_views) - 1 +let s:self.updated = 1 +let s:self._help = 0 +let s:self._task = 0 +let s:self._event = 0 +let s:self._help_order = [] +let s:self._event_order = [] + +function! s:self.set_calendar_views(views) dict abort + let views = [ 'year', 'month', 'week', 'weekday', 'day_7', 'day_6', 'day_5', 'day_4', 'day_3', 'day_2', 'day_1', 'day', 'clock', 'event', 'agenda' ] + let calendar_views = filter(a:views, 'index(views, v:val) >= 0') + if len(calendar_views) > 0 + let self.calendar_views = calendar_views + let self.index_max = len(self.calendar_views) - 1 + endif + return self +endfunction + +function! s:self.get_calendar_views() dict abort + return self.calendar_views[self.index] +endfunction + +function! s:self.set_index(view) dict abort + let i = index(self.calendar_views, a:view) + if i < 0 + if a:view ==# 'day' + let i = index(self.calendar_views, 'day_1') + elseif a:view ==# 'days' + let days = filter(copy(self.calendar_views), 'v:val =~# "^day_[2-6]"') + if len(days) + let i = index(self.calendar_views, days[0]) + endif + elseif a:view ==# 'week' + let i = index(self.calendar_views, 'day_7') + endif + endif + let self.index = i < 0 ? 0 : i + let self.updated = 1 + return self +endfunction + +function! s:self.change_index(diff) dict abort + if calendar#setting#get('cyclic_view') + let m = self.index_max + 1 + let self.index = (((self.index + a:diff) % m) + m) % m + else + let self.index = min([max([self.index + a:diff, 0]), self.index_max]) + endif + let self.updated = 1 +endfunction + +function! s:self.event_visible() dict abort + return self._event +endfunction + +function! s:self.task_visible() dict abort + return self._task +endfunction + +function! s:self.set_task_visibility(_task) dict abort + let self._task = type(a:_task) == type('') ? a:_task ==# '1' : a:_task +endfunction + +function! s:self.help_visible() dict abort + return self._help +endfunction + +function! s:self.set_view_source(source) dict abort + let self.source = a:source + let self.views = map(deepcopy(self.source), 'calendar#view#{v:val.type}#new(v:val)') + let self.order = range(len(self.source)) + return self +endfunction + +function! s:self.current_view() dict abort + return self.views[self.current_view_index()] +endfunction + +function! s:self.current_view_index() dict abort + let i = len(self.order) - 1 + while !self.views[self.order[i]].is_visible() + let i -= 1 + endwhile + return self.order[i] +endfunction + +function! s:self.view_count() dict abort + let num = 0 + for i in range(len(self.order)) + let num += self.views[self.order[i]].is_visible() + endfor + return num +endfunction + +function! s:self.visible_num() dict abort + let num = 0 + for i in range(len(self.views)) + if self.views[i].is_visible() + let num += 1 + endif + endfor + return num +endfunction + +function! s:self.event_view() dict abort + for i in range(len(self.views)) + if self.views[i].source.type ==# 'event' + return self.views[i] + endif + endfor +endfunction + +function! s:self.get_overlap() dict abort + let height = calendar#util#winheight() + let diffy = max([(height - self.ymax()) / 2, 0]) + let o = [] + let lw = [] + for i in range(height) + call add(o, []) + call add(lw, []) + endfor + let f = 0 + if self.visible_num() > 1 + for i in range(len(self.order)) + let c = self.views[self.order[i]] + if c.is_visible() + let [p, l, h, w] = [c.get_top() + (c.is_absolute() ? 0 : diffy), c.get_left(), c.sizey(), c.sizex()] + let r = range(p, p + h - 1) + for j in r + if j < len(o) + call add(o[j], i) + call add(lw[j], [l, w]) + if len(o[j]) <= 1 + continue + else + let f = 1 + if len(o[j]) == 2 + if lw[j][0][0] <= l && lw[j][0][0] + lw[j][0][1] >= l + call insert(o[j], -1) + elseif lw[j][0][0] >= l + if lw[j][0][0] < l + w + call insert(o[j], -1) + else + let o[j] = [o[j][1], o[j][0]] + endif + endif + else + call insert(o[j], -1) + endif + endif + endif + endfor + endif + endfor + endif + return [f, o, diffy] +endfunction + +function! s:self.ymax() dict abort + let d = len(self.order) + let ymax = 0 + for i in range(d) + let c = self.views[self.order[i]] + if c.is_visible() && !c.is_absolute() + let ymax = max([ymax, c.get_top() + c.sizey()]) + endif + endfor + return ymax +endfunction + +let [s:height, s:width] = [0, 0] +function! s:self.gather(...) dict abort + let d = len(self.order) + let updated = self.updated || a:0 && a:1 + for i in range(d) + let c = self.views[self.order[i]] + call c.set_index(self.calendar_views[self.index]) + call c.set_size() + let updated = updated || (c.is_visible() && c.updated()) " Do not break + endfor + if !updated | return 1 | endif + let self.updated = 0 + let [height, width] = [calendar#util#winheight(), calendar#util#winwidth()] + if [s:height, s:width] != [height, width] + let [s:height, s:width] = [height, width] + let s:texts = map(range(s:height), 'calendar#text#new(repeat(" ", s:width), 0, v:val, "")') + let s:llen = map(range(s:height), '0') + endif + let texts = deepcopy(s:texts) + let llen = deepcopy(s:llen) + let index = self.current_view_index() + let [f, v, diffy] = self.get_overlap() + for i in range(d) + let c = self.views[self.order[i]] + if !c.is_visible() + continue + endif + call c.set_selected(self.order[i] == index) + let r = c.gather(c.is_absolute() ? 0 : diffy) + for t in r + if 0 <= t.y && t.y < height + if t.t && llen[t.y] + call t.move(llen[t.y], 0) + endif + if f && t.t + call s:split_over(t, texts, v, llen, i, height) + endif + let l = texts[t.y].over(t) + if !t.t | let llen[t.y] = l | endif + endif + endfor + endfor + return texts +endfunction + +function! s:split_over(t, texts, v, llen, i, height) abort + let t = a:t + if len(t.syn) && len(t.syn[0]) == 5 + let flg = 0 + for k in range(len(t.syn)) + for j in range(min([t.syn[k][4], a:height - t.y])) + let flg = flg || len(a:v[t.y + j]) > 1 && a:v[t.y + j][0] != a:i + endfor + if flg | break | endif + endfor + if flg + for s in t.split() + if s.y < a:height + call s.move(a:llen[s.y] - a:llen[t.y], 0) + call a:texts[s.y].over(s) + endif + endfor + endif + endif +endfunction + +function! s:self.action(action) dict abort + let ret = self.current_view().action(a:action) + if type(ret) == 0 && ret == 0 + if a:action ==# 'redraw' + call b:calendar.update_force_redraw() + return 1 + elseif a:action ==# 'tab' + if self.view_count() > 1 && !self.current_view().on_top() + let index = self.current_view_index() + let next = index + while !self.views[next].is_visible() || next == index + let next = (next + 1) % len(self.views) + endwhile + let idx = index(self.order, next) + if idx >= 0 + call remove(self.order, idx) + let self.order = add(self.order, next) + endif + endif + elseif a:action ==# 'shift_tab' + if self.view_count() > 1 && !self.current_view().on_top() + let index = self.current_view_index() + let next = index + while !self.views[next].is_visible() || next == index + let next = (next - 1 + len(self.views)) % len(self.views) + endwhile + let idx = index(self.order, next) + if idx >= 0 + call remove(self.order, idx) + let self.order = add(self.order, next) + endif + endif + elseif a:action ==# 'status' + let select = calendar#day#join_date(b:calendar.day().get_ymd()) + let selectmd = calendar#day#join_date(b:calendar.day().get_ymd()[1:]) + let today = calendar#day#join_date(calendar#day#today().get_ymd()) + let diffnum = b:calendar.day().sub(calendar#day#today()) + let diff = diffnum >= 0 ? '+' . diffnum : '' . diffnum + let todaystr = calendar#message#get('today') + let dayof = b:calendar.day().sub(b:calendar.day().year().head_day()) + 1 + let yeardays = b:calendar.day().year().last_day().sub(b:calendar.day().year().head_day()) + 1 + let daypercent = 100 * dayof / yeardays + let message = printf('%s %s/%s --%d%%-- %s %s %s', select, dayof, yeardays, daypercent, todaystr, today, diff) + let winw = calendar#util#winwidth() - 14 + if calendar#string#strdisplaywidth(message) > winw + let message = printf('%s %s/%s --%d%%-- %s %s', select, dayof, yeardays, daypercent, today, diff) + if calendar#string#strdisplaywidth(message) > winw + let message = printf('%s %s/%s %s %s', select, dayof, yeardays, today, diff) + if calendar#string#strdisplaywidth(message) > winw + let message = printf('%s %s/%s', select, dayof, yeardays) + if calendar#string#strdisplaywidth(message) > winw + let message = printf('%s', select) + if calendar#string#strdisplaywidth(message) > winw + let message = printf('%s', selectmd) + endif + endif + endif + endif + endif + call calendar#echo#message(message) + elseif a:action ==# 'today' + call b:calendar.move_day(-b:calendar.day().sub(calendar#day#today())) + call b:calendar.move_second(-b:calendar.time().sub(calendar#time#now())) + elseif a:action ==# 'help' + let self.updated = 1 + let ii = -1 + for i in range(len(self.order)) + if self.views[i].source.type ==# 'help' + let ii = i + endif + endfor + let self._help = !self._help + if ii >= 0 && self._help + let self._help_order = copy(self.order) + let i = index(self.order, ii) + if i >= 0 + call remove(self.order, i) + let self.order = add(self.order, ii) + endif + elseif has_key(self, '_help_order') + let self.order = self._help_order + let self._help = 0 + endif + elseif a:action ==# 'task' + if self.current_view().on_top() && self.current_view().source.type !=# 'task' + return + endif + let self.updated = 1 + let ii = -1 + for i in range(len(self.order)) + if self.views[i].source.type ==# 'task' + let ii = i + endif + endfor + let self._task = !self._task + if ii >= 0 && self._task + let self._task_order = copy(self.order) + let i = index(self.order, ii) + if i >= 0 + let self.order = self.order[i + 1:] + self.order[:i] + endif + elseif has_key(self, '_task_order') + let self.order = self._task_order + let self._task = 0 + elseif ii >= 0 && !self._task + let self.order = filter(copy(self.order), 'v:val != ii') + [ii] + endif + elseif a:action ==# 'close_task' + if self._task + call self.action('task') + endif + elseif a:action ==# 'event' + if self.current_view().on_top() && self.current_view().source.type !=# 'event' + return + endif + let self.updated = 1 + let ii = -1 + for i in range(len(self.order)) + if self.views[i].source.type ==# 'event' + let ii = i + endif + endfor + let self._event = !self._event + if ii >= 0 && self._event + let self._event_order = copy(self.order) + let i = index(self.order, ii) + if i >= 0 + let self.order = self.order[i + 1:] + self.order[:i] + endif + elseif has_key(self, '_event_order') + let self.order = self._event_order + let self._event = 0 + endif + elseif a:action ==# 'close_event' + if self._event + call self.action('event') + endif + elseif a:action ==# 'hide' + try + bunload! + catch + enew! + endtry + return 1 + elseif a:action ==# 'exit' + bwipeout! + return 1 + elseif a:action ==# 'view_left' + call self.change_index(-v:count1) + elseif a:action ==# 'view_right' + call self.change_index(v:count1) + elseif a:action ==# 'command_enter' && mode() ==# 'c' + if getcmdtype() ==# ':' + let cmd = calendar#util#getcmdline() + let digits = [] + if cmd =~# '\v^\s*marks\s*$' + call b:calendar.mark.showmarks() + return calendar#util#update_keys() + elseif cmd =~# '\v^\s*(ma%[rk]\s+|k\s*)[a-z]\s*$' + let mark = matchstr(cmd, '\v[a-z](\s*$)@=') + call b:calendar.mark.set(mark) + return calendar#util#update_keys() + elseif cmd =~# '\v^\s*delm%[arks]!\s*$' + call b:calendar.mark.delmarks() + return calendar#util#update_keys() + elseif cmd =~# '\v^\s*delm%[arks]\s+[a-z]\s*$' + let mark = matchstr(cmd, '\v[a-z](\s*$)@=') + call b:calendar.mark.delmarks(mark) + return calendar#util#update_keys() + elseif cmd =~# '\v^\s*\d+\s*$' + return calendar#util#update_keys() + elseif cmd =~# '\v^\s*\d+\s*/\s*\d+\s*(/\s*\d+\s*)?$' + let digits = map(split(cmd, '/'), 'matchstr(v:val, "\\v\\d+") * 1') + elseif cmd =~# '\v^\s*\d+\s*-\s*\d+\s*(-\s*\d+\s*)?$' + let digits = map(split(cmd, '-'), 'matchstr(v:val, "\\v\\d+") * 1') + elseif cmd =~# '\v^\s*\d+\s*\.\s*\d+\s*(\.\s*\d+\s*)?$' + let digits = map(split(cmd, '\.'), 'matchstr(v:val, "\\v\\d+") * 1') + elseif cmd =~# '\v^\s*\d+\s+\d+\s*(\s+\d+\s*)?$' + let digits = map(split(cmd, '\s\+'), 'matchstr(v:val, "\\v\\d+") * 1') + elseif cmd =~# '\v^\s*\d*\s*(\<\s*)+\d*$' + let c = matchstr(cmd, '\d\+') + let d = len(cmd) - len(substitute(cmd, '<', '', 'g')) + call self.change_index(-max([len(c) ? c + 0 : 1, 1]) * d) + return calendar#util#update_keys() + elseif cmd =~# '\v^\s*\d*\s*(\>\s*)+\d*$' + let c = matchstr(cmd, '\d\+') + let d = len(cmd) - len(substitute(cmd, '>', '', 'g')) + call self.change_index(max([len(c) ? c + 0 : 1, 1]) * d) + return calendar#util#update_keys() + endif + if len(digits) + call b:calendar.set_day(calendar#argument#day(digits, b:calendar.day().get_ymd())) + call b:calendar.set_month() + return calendar#util#update_keys() + else + return "\" + endif + else + return "\" + endif + endif + endif + return ret +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/webapi.vim b/bundle/calendar.vim/autoload/calendar/webapi.vim new file mode 100644 index 000000000..71f846da8 --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/webapi.vim @@ -0,0 +1,384 @@ +" ============================================================================= +" Filename: autoload/calendar/webapi.vim +" Author: itchyny +" License: MIT License +" Last Change: 2019/12/03 12:48:49. +" ============================================================================= + +" Web interface. +" Most part of this file was copied from webapi-vim and vital.vim. +" Thank you Yasuhiro Matsumoto, for distributing useful scripts under public +" domain. + +" Maintainer and License of the original script {{{ +" Last Change: 2010-09-10 +" Maintainer: Yasuhiro Matsumoto +" License: This file is placed in the public domain. +" }}} + +let s:save_cpo = &cpo +set cpo&vim + +let s:cache = calendar#cache#new('download') +call s:cache.check_dir(1) +if !calendar#setting#get('debug') + call s:cache.rmdir_on_exit() +endif + +function! s:nr2byte(nr) abort + if a:nr < 0x80 + return nr2char(a:nr) + elseif a:nr < 0x800 + return nr2char(a:nr/64+192).nr2char(a:nr%64+128) + elseif a:nr < 0x10000 + return nr2char(a:nr/4096%16+224).nr2char(a:nr/64%64+128).nr2char(a:nr%64+128) + elseif a:nr < 0x200000 + return nr2char(a:nr/262144%16+240).nr2char(a:nr/4096/16+128).nr2char(a:nr/64%64+128).nr2char(a:nr%64+128) + elseif a:nr < 0x4000000 + return nr2char(a:nr/16777216%16+248).nr2char(a:nr/262144%16+128).nr2char(a:nr/4096/16+128).nr2char(a:nr/64%64+128).nr2char(a:nr%64+128) + else + return nr2char(a:nr/1073741824%16+252).nr2char(a:nr/16777216%16+128).nr2char(a:nr/262144%16+128).nr2char(a:nr/4096/16+128).nr2char(a:nr/64%64+128).nr2char(a:nr%64+128) + endif +endfunction + +function! s:nr2enc_char(charcode) abort + if &encoding == 'utf-8' + return nr2char(a:charcode) + endif + let char = s:nr2byte(a:charcode) + if strlen(char) > 1 + let char = strtrans(iconv(char, 'utf-8', &encoding)) + endif + return char +endfunction + +function! calendar#webapi#get(url, ...) abort + return s:request(1, {}, a:url, get(a:000, 0, {}), get(a:000, 1, {}), get(a:000, 2, 'GET')) +endfunction + +function! calendar#webapi#post(url, ...) abort + return s:request(1, {}, a:url, get(a:000, 0, {}), get(a:000, 1, {}), get(a:000, 2, 'POST')) +endfunction + +function! calendar#webapi#delete(url, ...) abort + return s:request(1, {}, a:url, get(a:000, 0, {}), get(a:000, 1, {}), get(a:000, 2, 'DELETE')) +endfunction + +function! calendar#webapi#patch(url, ...) abort + return s:request(1, {}, a:url, get(a:000, 0, {}), get(a:000, 1, {}), get(a:000, 2, 'PATCH')) +endfunction + +function! calendar#webapi#put(url, ...) abort + return s:request(1, {}, a:url, get(a:000, 0, {}), get(a:000, 1, {}), get(a:000, 2, 'PUT')) +endfunction + +function! calendar#webapi#post_nojson(url, ...) abort + return s:request(0, {}, a:url, get(a:000, 0, {}), get(a:000, 1, {}), get(a:000, 2, 'POST')) +endfunction + +function! calendar#webapi#get_async(id, cb, url, ...) abort + return s:request(1, { 'id': a:id, 'cb': a:cb } , a:url, get(a:000, 0, {}), get(a:000, 1, {}), get(a:000, 2, 'GET')) +endfunction + +function! calendar#webapi#post_async(id, cb, url, ...) abort + return s:request(1, { 'id': a:id, 'cb': a:cb }, a:url, get(a:000, 0, {}), get(a:000, 1, {}), get(a:000, 2, 'POST')) +endfunction + +function! calendar#webapi#delete_async(id, cb, url, ...) abort + return s:request(1, { 'id': a:id, 'cb': a:cb }, a:url, get(a:000, 0, {}), get(a:000, 1, {}), get(a:000, 2, 'DELETE')) +endfunction + +function! calendar#webapi#patch_async(id, cb, url, ...) abort + return s:request(1, { 'id': a:id, 'cb': a:cb }, a:url, get(a:000, 0, {}), get(a:000, 1, {}), get(a:000, 2, 'PATCH')) +endfunction + +function! calendar#webapi#put_async(id, cb, url, ...) abort + return s:request(1, { 'id': a:id, 'cb': a:cb }, a:url, get(a:000, 0, {}), get(a:000, 1, {}), get(a:000, 2, 'PUT')) +endfunction + +function! calendar#webapi#post_nojson_async(id, cb, url, ...) abort + return s:request(0, { 'id': a:id, 'cb': a:cb }, a:url, get(a:000, 0, {}), get(a:000, 1, {}), get(a:000, 2, 'POST')) +endfunction + +function! s:request(json, async, url, param, postdata, method) abort + let url = a:url + let paramstr = calendar#webapi#encodeURI(a:param) + let withbody = a:method !=# 'GET' && a:method !=# 'DELETE' + let header = {} + if paramstr !=# '' + let url .= '?' . paramstr + endif + let postfile = '' + if withbody + let postdatastr = a:json ? calendar#webapi#encode(a:postdata) : join(s:postdata(a:postdata), "\n") + let postfile = tempname() + call writefile(split(postdatastr, "\n"), postfile, 'b') + let header['Content-Length'] = len(postdatastr) + if a:json + let header['Content-Type'] = 'application/json' + endif + endif + let command = s:command(url, a:method, header, postfile, a:async == {} ? '' : s:cache.path(a:async.id)) + if type(command) != type('') + return { 'status': '0', 'message': '', 'header': '', 'content': '' } + endif + call s:cache.check_dir(1) + if a:async == {} + let data = calendar#util#system(command) + let response = calendar#webapi#parse(split(data, "\n")) + if withbody + call delete(postfile) + endif + return response + else + if !calendar#setting#get('debug') + call s:cache.delete(a:async.id) + endif + call calendar#async#new('calendar#webapi#callback(' . string(a:async.id) . ',' . string(a:async.cb) . ')') + if has('win32') + call calendar#util#system('cmd /c start /min ' . command) + else + let command .= ' &' + call calendar#util#system(command) + endif + endif +endfunction + +function! s:command(url, method, header, postfile, output) abort + let quote = s:_quote() + if executable('curl') + let command = 'curl --http1.1 --suppress-connect-headers -s -k -i -N -X ' . a:method + let command .= s:make_header_args(a:header, '-H ', quote) + if a:postfile !=# '' + let command .= ' --data-binary @' . quote . a:postfile . quote + endif + if a:output !=# '' + let command .= ' -o ' . quote . a:output . quote + endif + let command .= ' ' . quote . a:url . quote + return command + elseif executable('wget') + let command = 'wget -O- --server-response -q' + let a:header['X-HTTP-Method-Override'] = a:method + let command .= s:make_header_args(a:header, '--header=', quote) + if a:postfile !=# '' + let command .= ' --post-file=' . quote . a:postfile . quote + else + let command .= ' --method=' . a:method + endif + let command .= ' ' . quote . a:url . quote + if a:output !=# '' + let command .= ' > ' . quote . a:output . quote . ' 2>&1' + endif + return command + else + call calendar#echo#error_message('curl_wget_not_found') + return 1 + endif +endfunction + +let s:callback_datalen = {} +function! calendar#webapi#callback(id, cb) abort + let data = s:cache.get_raw(a:id) + if type(data) != type([]) + return 1 + endif + let prevdatalen = get(s:callback_datalen, a:id) + let s:callback_datalen[a:id] = len(data) + if len(data) == 0 || len(data) != prevdatalen + return 1 + endif + let response = calendar#webapi#parse(data) + if empty(response) + return 1 + elseif a:cb !=# '' + call call(a:cb, [a:id, response]) + endif + if !calendar#setting#get('debug') + call s:cache.delete(a:id) + endif + unlet s:callback_datalen[a:id] + return 0 +endfunction + +function! calendar#webapi#parse(data) abort + if len(a:data) == 0 + return { 'status': '0', 'message': '', 'header': '', 'content': '' } + endif + let i = 0 + while i < len(a:data) && a:data[i] =~# '^ ' " for wget + let a:data[i] = a:data[i][2:] + let i += 1 + endwhile + if i > 0 + call insert(a:data, '', i) + let i = 0 + endif + while i < len(a:data) && (a:data[i] =~# '\v^HTTP/[12]%(\.\d)? 3' || + \ (i + 2 < len(a:data) && a:data[i] =~# '\v^HTTP/1\.\d \d{3}' && + \ a:data[i + 1] =~# '\v^\r?$' && a:data[i + 2] =~# '\v^HTTP/1\.\d \d{3}')) + while i < len(a:data) && a:data[i] !~# '\v^\r?$' + let i += 1 + endwhile + let i += 1 + endwhile + while i < len(a:data) && a:data[i] !~# '\v^\r?$' + let i += 1 + endwhile + let header = a:data[:i] + let content = join(a:data[(i):], "\n") + let matched = matchlist(get(header, 0, ''), '\v^HTTP/[12]%(\.\d)?\s+(\d+)\s*(.*)') + if !empty(matched) + let [status, message] = matched[1 : 2] + call remove(header, 0) + else + let [status, message] = ['200', 'OK'] + endif + return { 'status': status, 'message': message, 'header': header, 'content': content } +endfunction + +function! calendar#webapi#null() abort + return 0 +endfunction + +function! calendar#webapi#true() abort + return 1 +endfunction + +function! calendar#webapi#false() abort + return 0 +endfunction + +function! calendar#webapi#encode(val) abort + if type(a:val) == 0 + return a:val + elseif type(a:val) == 1 + let json = '"' . escape(a:val, '\"') . '"' + let json = substitute(json, "\r", '\\r', 'g') + let json = substitute(json, "\n", '\\n', 'g') + let json = substitute(json, "\t", '\\t', 'g') + let json = substitute(json, '\([[:cntrl:]]\)', '\=printf("\x%02d", char2nr(submatch(1)))', 'g') + return iconv(json, &encoding, 'utf-8') + elseif type(a:val) == 2 + let s = string(a:val) + if s == "function('calendar#webapi#null')" + return 'null' + elseif s == "function('calendar#webapi#true')" + return 'true' + elseif s == "function('calendar#webapi#false')" + return 'false' + endif + elseif type(a:val) == 3 + return '[' . join(map(copy(a:val), 'calendar#webapi#encode(v:val)'), ',') . ']' + elseif type(a:val) == 4 + return '{' . join(map(keys(a:val), 'calendar#webapi#encode(v:val).":".calendar#webapi#encode(a:val[v:val])'), ',') . '}' + else + return string(a:val) + endif +endfunction + +function! calendar#webapi#decode(json) abort + let json = iconv(a:json, 'utf-8', &encoding) + let json = substitute(json, '[\r\n]', '', 'g') + let json = substitute(json, '\\x22\|\\u0022', '\\"', 'g') + if v:version > 703 || v:version == 703 && has('patch780') + let json = substitute(json, '\\u\(\x\x\x\x\)', '\=iconv(nr2char(str2nr(submatch(1), 16), 1), "utf-8", &encoding)', 'g') + else + let json = substitute(json, '\\u\(\x\x\x\x\)', '\=s:nr2enc_char("0x".submatch(1))', 'g') + endif + let [null,true,false] = [0,1,0] + try + sandbox let ret = eval(json) + catch + let ret = {} + endtry + return ret +endfunction + +function! calendar#webapi#open_url(url) abort + if has('win32') + silent! call calendar#util#system('cmd /c start "" "' . a:url . '"') + elseif executable('xdg-open') + silent! call calendar#util#system('xdg-open "' . a:url . '" &') + elseif executable('open') + silent! call calendar#util#system('open "' . a:url . '" &') + endif +endfunction + +function! calendar#webapi#echo_error(response) abort + let message = get(a:response, 'message', '') + if has_key(a:response, 'content') + let cnt = calendar#webapi#decode(a:response.content) + if type(cnt) == type({}) && len(get(get(cnt, 'error', {}), 'message', '')) + let message = get(get(cnt, 'error', {}), 'message', '') + endif + endif + if message !=# '' + call calendar#echo#error(message) + endif +endfunction + +function! s:make_header_args(headdata, option, quote) abort + let args = '' + for key in keys(a:headdata) + unlet! value + let value = type(a:headdata[key]) == type('') || type(a:headdata[key]) == type(0) ? a:headdata[key] : + \ type(a:headdata[key]) == type({}) ? '' : + \ type(a:headdata[key]) == type([]) ? '[' . join(map(a:headdata[key], 's:make_header_args(v:val, a:option, a:quote)'), ',') . ']' : '' + if has('win32') + let value = substitute(value, '"', '"""', 'g') + endif + let args .= ' ' . a:option . a:quote . key . ': ' . value . a:quote + endfor + return args +endfunction + +function! s:decodeURI(str) abort + let ret = a:str + let ret = substitute(ret, '+', ' ', 'g') + let ret = substitute(ret, '%\(\x\x\)', '\=printf("%c", str2nr(submatch(1), 16))', 'g') + return ret +endfunction + +function! s:escape(str) abort + return substitute(a:str, '[^a-zA-Z0-9_.-]', '\=printf("%%%02X", char2nr(submatch(0)))', 'g') +endfunction + +function! calendar#webapi#encodeURI(items) abort + let ret = '' + if type(a:items) == type({}) + for key in sort(keys(a:items)) + if ret !=# '' + let ret .= '&' + endif + let ret .= key . '=' . calendar#webapi#encodeURI(a:items[key]) + endfor + elseif type(a:items) == type([]) + for item in sort(a:items) + if ret !=# '' + let ret .= '&' + endif + let ret .= item + endfor + else + let ret = s:escape(a:items) + endif + return ret +endfunction + +function! s:postdata(data) abort + if type(a:data) == type({}) + return [calendar#webapi#encodeURI(a:data)] + elseif type(a:data) == type([]) + return a:data + else + return split(a:data, "\n") + endif +endfunction + +function! s:_quote() abort + return &shellxquote == '"' ? "'" : '"' +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/autoload/calendar/week.vim b/bundle/calendar.vim/autoload/calendar/week.vim new file mode 100644 index 000000000..aaef573ec --- /dev/null +++ b/bundle/calendar.vim/autoload/calendar/week.vim @@ -0,0 +1,62 @@ +" ============================================================================= +" Filename: autoload/calendar/week.vim +" Author: itchyny +" License: MIT License +" Last Change: 2017/05/07 23:07:36. +" ============================================================================= + +let s:save_cpo = &cpo +set cpo&vim + +let s:weeks = [ 'sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday' ] + +let s:cache = {} +function! calendar#week#first_day_index() abort + let first_day = calendar#setting#get('first_day') + if has_key(s:cache, first_day) + return s:cache[first_day] + endif + let index = index(s:weeks, tolower(first_day)) + let s:cache[first_day] = index >= 0 ? index : 0 + return s:cache[first_day] +endfunction + +function! calendar#week#last_day_index() abort + return (calendar#week#first_day_index() + 6) % 7 +endfunction + +function! calendar#week#is_first_day(day) abort + return a:day.week() == calendar#week#first_day_index() +endfunction + +function! calendar#week#is_last_day(day) abort + return a:day.week() == calendar#week#last_day_index() +endfunction + +function! calendar#week#week_index(day) abort + return (a:day.week() + 7 - calendar#week#first_day_index()) % 7 +endfunction + +function! calendar#week#week_count(month) abort + return (a:month.last_day().sub(a:month.head_day()) + 1 + calendar#week#week_index(a:month.head_day()) + 6) / 7 +endfunction + +function! calendar#week#week_number(day) abort + if calendar#setting#get('first_day') =~? 'monday' + let d = a:day.year().head_day().add(3) + let diff = a:day.sub(d) + calendar#week#week_index(d) + if diff >= 0 + return (diff + 7) / 7 + else + let day = d.add(-4) + let d = day.year().head_day().add(3) + return (day.sub(d) + calendar#week#week_index(d) + 7) / 7 + endif + else + let d = a:day.year().head_day() + return (a:day.sub(d) + calendar#week#week_index(d) + 7) / 7 + endif +endfunction + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/doc/calendar.txt b/bundle/calendar.vim/doc/calendar.txt new file mode 100644 index 000000000..80fc2efd9 --- /dev/null +++ b/bundle/calendar.vim/doc/calendar.txt @@ -0,0 +1,1093 @@ +*calendar.txt* A calendar application for Vim + +Version: 0.0 +Author: itchyny (https://github.com/itchyny) +License: MIT License +Repository: https://github.com/itchyny/calendar.vim +Last Change: 2020/12/31 01:59:11. + +CONTENTS *calendar-contents* + +Introduction |calendar-introduction| +Concept |calendar-concept| +Vim application |calendar-vim-application| +Commands |calendar-commands| +Options |calendar-options| +View |calendar-view| +Key Mappings |calendar-key-mappings| +Marks |calendar-marks| +Input Format |calendar-input-format| +Troubleshooting |calendar-troubleshooting| +Changelog |calendar-changelog| + +============================================================================== +INTRODUCTION *calendar-introduction* + +The *calendar.vim* is a modern and ultimate *calendar* application for Vim. + +The mattn's |calendar.vim| plugin was a great plugin. +(http://www.vim.org/scripts/script.php?script_id=52) +The plugin provides a calendar window within Vim, with a diary feature, both +vertical/horizontal view and printing week number. The plugin has, as you +guess from the fact that its script id is 52, played an important role to show +the potential of Vim script in its early stage. The only problem is that the +source codes of the plugin are not so clean and hard to modify. Couldn't be +helped. Remember that it was written without using dictionary and list. + +My |calendar.vim| plugin basically provides what is provided by mattn's +plugin: calendar of the nearest months, both horizontal and vertical view, and +large-size calendar. Also, this plugin provides many key mappings to move +around the calendar. The default key mappings are carefully designed to match +the default key mappings of Vim itself. Of course, users can freely configure +key mappings in |calendar| buffers. + +This |calendar| plugin also supports importing events from Google Calendar. +Once the user connects this plugin to Google Calendar, you can freely edit, +create, and delete events in Vim. The events are automatically synchronized +with Google Calendar. + +Moreover, the Julian calendar is supported in this plugin. Basically in the +history of calendars, there are two kinds of calendars: the Julian calendar +and the Gregorian calendar. In most countries (for example, Holy Rome Empire, +France and Spain) the Julian calendar was replaced with the Gregorian in +October of 1582, so the |calendar| adopts this boundary date by default. +However, in the British Empire, it was switched in 1752, and in Russia, in +1918. The |calendar| plugin provides a way to configure the date in which the +Julian calendar is switched to the Gregorian calendar. The plugin also +provides a way to view the Julian calendar in the present day, and vice versa. + +------------------------------------------------------------------------------ +CONCEPT *Calendar-Concept* +This is a calendar which is ... + + Comfortable > + The key mappings are designed to match the default mappings of Vim. +< + Powerful > + The application can be connected to Google Calendar and used in your + life. +< + Elegant > + The appearance is carefully designed, dropping any unnecessary + information. +< + Interesting > + You can choose the calendar in Julian calendar or in Gregorian + calendar. +< + Useful > + To conclude, very useful. +< +------------------------------------------------------------------------------ +VIM APPLICATION *calendar-vim-application* +There are lots of Vim plugins. We can classify them as the following groups. + - colorscheme plugins > + (e.g. wombat) +< - syntax plugins > + (e.g. vim-json, syntaxm4.vim) +< - edit assistance plugins > + (e.g. completion plugins, comment plugins) +< - special buffer plugins > + (e.g. VimFiler, TweetVim, gmail.vim) +< - plugins extending the function of a plugin > + (e.g. some unite sources) +< - plugins supporting other plugins with some low-layer features > + (e.g. vital.vim, vimproc, webapi-vim) + + (create a special buffer and provides some features inside it) +< - use a buffer as a display for the state of the plugin > + (do not get information from the buffer, redraw entirely every time) +< - provide a rich interface > + (for example, window layers composition) +< - be coded with loose coupling > + (any two files do not have common code) +< - be independent to any other plugins > + (all the requirements are included) + + :Calendar -year={num} -month={num} -day={num} +< See |calendar-options-year|, |calendar-options-month| and + |calendar-options-day| for more information. + +------------------------------------------------------------------------------ +OPTIONS *calendar-options* + +You can use the following options to change the location of the |calendar| +buffer. + + *calendar-options-split* + -split={horizontal/vertical} + Open the calendar buffer in a horizontally/vertically opened + buffer. + + *calendar-options-position* + -position={below/tab/here/left/right/topleft/topright} + -position=below + Open the buffer below. + -position=tab + Open the buffer in a new tab. + -position=here[!] + Open the buffer at the same window of the current + buffer. If some changes exist in the current buffer, + this option is ignored. An '!' is added to discard + any changes in the current buffer. + -position=left + Open the buffer on the left hand side. + -position=right + Open the buffer on the right hand side. + -position=topleft + Open the buffer on the left hand side, with full + height of Vim. + -position=topright + Open the buffer on the right hand side, with full + height of Vim. + +You can use the following options to change the size of the |calendar| buffer. + + *calendar-options-height* + -height={num} + Open the calendar buffer with the specified height. This + option is effective with -split=horizontal. + + *calendar-options-width* + -width={num} + Open the calendar buffer with the specified width. This + option is effective with -split=vertical. + +You can explicitly give the date with arguments. + + *calendar-options-year* + -year={num} + *calendar-options-month* + -month={num} + *calendar-options-day* + -day={num} + Open the calendar with the specified date. + +The following options change the appearance of the calendar. + + *calendar-options-locale* + *g:calendar_locale* + -locale={default/en/ja} + let g:calendar_locale = "{default/en/ja}" + Specify the locale of the messages in the calendar buffer. + The default value is "default", which detects the value of + |v:lang|. + + *calendar-options-first_day* + *g:calendar_first_day* + -first_day={sunday/monday/tuesday/wednesday/thursday/friday/saturday} + let g:calendar_first_day = "{sunday/monday/...}" + Specify the first day of the calendars. + The default value is based on |v:lang|. + "sunday": United States, Canada, Japan, Israel + "monday": Other countries + + *calendar-options-time_zone* + *g:calendar_time_zone* + -time_zone={[-+]hhmm} + let g:calendar_time_zone = "{[-+]hhmm}" + Specify the time zone from UTC. + The default value is strftime('%z'). + + *calendar-options-date_endian* + *g:calendar_date_endian* + -date_endian={little/big/middle} + let g:calendar_date_endian = "{little/big/middle}" + The format of dates. + -date_endian=little : day/month/year + -date_endian=big : year/month/day + -date_endian=middle : month/day/year + The default value is based on |v:lang| + big : Japan, China, Korea, Hungary, + Lithuania, Mongolia + middle : United States + little : Other countries + + *calendar-options-date_separator* + *g:calendar_date_separator* + -date_separator={ / - . " " } + let g:calendar_date_separator={"/" "-" "." " "} + The separator of dates. + The default value is based on |v:lang|. + '.' : Armenia, Austria, Azerbaijan, Belarus, Bulgaria, + Croatia, Czech Republic, Estonia, Finland, + Georgia, Germany, Hungary, Iceland, + Kazakhstan, Kyrgyzstan, Latvia, Mongolia, + Norway, Romania, Russia, Slovakia, + Switzerland, Turkmenistan, Ukraine + '-' : Bangladesh, China, Denmark, France, India, + Ireland, Lithuania, Netherlands, Sweden, + Taiwan + '/' : Other countries + + *calendar-options-date_month_name* + *g:calendar_date_month_name* + -date_month_name[!] + let g:calendar_date_month_name={0/1} + If on, a date string uses month names. In order to disable + this option with the argument, add the trailing '!'. + The default value is 0. + + *calendar-options-date_full_month_name* + *g:calendar_date_full_month_name* + -date_full_month_name[!] + let g:calendar_date_full_month_name={0/1} + If on, a date string uses the full month names. In order to + disable this option with the argument, add the trailing '!'. + The default value is 0. + + *calendar-options-week_number* + *g:calendar_week_number* + -week_number[!] + let g:calendar_week_number={0/1} + If on, it shows the week numbers. In order to disable + this option with the argument, add the trailing '!'. + The default value is 0. + + *calendar-options-task* + *g:calendar_task* + -task[!] + let g:calendar_task={0/1} + If on, the app shows the task list on its startup. You can + toggle the task list with the T key, which is mapped to + |(calendar_task)|. If you want to disable the visibility + of the task list after you set the global variable on, add the + trailing '!'. + The default value is 0. + + *calendar-options-event_start_time* + *g:calendar_event_start_time* + -event_start_time[!] + let g:calendar_event_start_time={0/1} + If on, it shows the starting time of the events in the + month/days views. In order to disable this option from + the argument, add the trailing '!'. + The default value is 1. + + *calendar-options-event_start_time_minwidth* + *g:calendar_event_start_time_minwidth* + -event_start_time_minwidth=[num] + let g:calendar_event_start_time_minwidth=[num] + The minimum width for showing the starting time of the events. + If the width of the each day is larger than or equals to this + value, it shows the starting time of the events. + The default value is 16. + + *calendar-options-clock_12hour* + *g:calendar_clock_12hour* + -clock_12hour[!] + let g:calendar_clock_12hour={0/1} + If on, times are displayed in 12-hour clock style. In order to + disable this option with the argument, add the trailing '!'. + The default value is 0. + + *calendar-options-frame* + *g:calendar_frame* + -frame={default/unicode/space/unicode_bold/unicode_round/unicode_double} + let g:calendar_frame = "{default/unicode/...}" + The format of frames. The unicode-prefix values are available + when |'enc'| is 'utf-8' and |'fenc'| is 'utf-8'. + The default value is: + "unicode": If |'enc'| is 'utf-8' and |'fenc'| is 'utf-8' + "default": In other cases + + *calendar-options-task_width* + *g:calendar_task_width* + -task_width={number} + let g:calendar_task_width = {number} + The width of the task list window. + The default value is 1/6 of the window width. + + *calendar-options-message_prefix* + *g:calendar_message_prefix* + -message_prefix="{string}" + let g:calendar_message_prefix = "{string}" + The prefix of the messages. + The default value is: "[calendar] ". + +This application has some different views. You can switch views with |<| and +|>| keys. You can change the initial view. + + *calendar-options-view* + *g:calendar_view* + -view={year/month/week/days/day/clock/event/agenda} + let g:calendar_view = "{year/month/week/days/day/clock/event/agenda}" + Specify the view of the calendar on starting the buffer. + The default value is "month". + + *g:calendar_views* + let g:calendar_views = ['year', 'month', ... ] + Specify the views in an array. + The default value is: > + ['year', 'month', 'week', 'day_4', 'day', 'clock'] +< The available views are: > + 'year', 'month', 'week', 'weekday', + 'day_7', 'day_6', 'day_5', 'day_4', + 'day_3', 'day_2', 'day_1', 'day', + 'clock', 'event', 'agenda' +< + *calendar-options-cyclic_view* + *g:calendar_cyclic_view* + -cyclic_view[!] + let g:calendar_cyclic_view = {0/1} + If this value is 1 or the argument is given, the keys |<| and + |>| do not stop at the leftmost/rightmost views, but change + the view cyclically. + The default value is 0. + +In order to connect this application to Google, you should use the following +options. + *calendar-options-google_calendar* + *g:calendar_google_calendar* + -google_calendar[!] + let g:calendar_google_calendar = {0/1} + If the value is 1 or the argument is given, this application + will download the calendars from Google Calendar, with your + permission. In order to disable this option with the argument, + add the trailing '!'. + The default value is 0. + + *calendar-options-google_task* + *g:calendar_google_task* + -google_task[!] + let g:calendar_google_task = {0/1} + If the value is 1 or the argument is given, this application + will download the tasks from Google Task, with your permission. + In order to disable this option with the argument, add the + trailing '!'. + The default value is 0. + +Other miscellaneous options. + + *calendar-options-calendar* + *g:calendar_calendar* + -calendar={default/gregorian/julian} + {austria/austriastyria/british/bulgaria/canada} + {estonia/france/germany/germanyprussia/greece} + {holland/hungary/italy/japan/poland/portugal} + {russia/spain/turkey/us} + let g:calendar_calendar = "{default/gregorian/julian/...}" + The date switching to Gregorian calendar varies. + The default value is "default", the switching date is + 15/10/1582. + Calendar Switching date (day month year) + default 15 10 1582 + italy 15 10 1582 + poland 15 10 1582 + portugal 15 10 1582 + spain 15 10 1582 + france 20 12 1582 + holland 1 1 1583 + germany 11 1 1583 + austria 16 10 1583 + austriastyria 25 12 1583 + hungary 1 11 1587 + germanyprussia 2 9 1610 + british 14 9 1752 + canada 14 9 1752 + us 14 9 1752 + japan 1 1 1873 + bulgaria 14 4 1916 + estonia 14 2 1918 + russia 14 2 1918 + greece 1 3 1923 + turkey 1 1 1927 + + *calendar-options-calendar_candidates* + *g:calendar_calendar_candidates* + -calendar_candidates=pattern1,pattern2,pattern3 + let g:calendar_calendar_candidates = ["pattern1", "pattern2", "pattern3"] + Specify the calendar candidates on inserting and moving a + calendar event. Note that the values are matched against the + summary of the calendars. + + *calendar-options-updatetime* + *g:calendar_updatetime* + -updatetime=[num] + let g:calendar_updatetime = [num] + Specify the updatetime (in msec) in the calendar buffer. This + value is used for asynchronous web queries and the clock view. + The default value is 200. + + *calendar-options-skip_event_delete_confirm* + *g:calendar_skip_event_delete_confirm* + -skip_event_delete_confirm[!] + let g:calendar_skip_event_delete_confirm = {0/1} + If the value is 1, the application skips confirmation on + deleting an event. + The default value is 0. + + *calendar-options-skip_task_delete_confirm* + *g:calendar_skip_task_delete_confirm* + -skip_task_delete_confirm[!] + let g:calendar_skip_task_delete_confirm = {0/1} + If the value is 1, the application skips confirmation on + deleting a task. + The default value is 0. + + *calendar-options-skip_task_clear_completed_confirm* + *g:calendar_skip_task_clear_completed_confirm* + -skip_task_clear_completed_confirm[!] + let g:calendar_skip_task_clear_completed_confirm = {0/1} + If the value is 1, the application skips confirmation on + completing a task. + The default value is 0. + + *calendar-options-yank_deleting* + *g:calendar_yank_deleting* + -yank_deleting[!] + let g:calendar_yank_deleting = {0/1} + If the value is 1 or the argument is given, the application + yanks the text when you delete an event or a task. + The default value is 1. + + *calendar-options-task_delete* + *g:calendar_task_delete* + -task_delete[!] + let g:calendar_task_delete = {0/1} + If the value is 1 or the argument is given, the application + deletes the selected task directly without completing. + The default value is 0. + + *calendar-options-cache_directory* + *g:calendar_cache_directory* + -cache_directory=[dir] + let g:calendar_cache_directory = [dir] + Specify the cache directory for this plugin. + The default value is ~/.cache/calendar.vim/. + + *calendar-options-debug* + *g:calendar_debug* + -debug[!] + let g:calendar_debug = {0/1} + If the value is 1 or the argument is given, the application + runs in debug mode. In debug mode: + 1. It does not delete all the downloaded files. + The default value is 0. + +------------------------------------------------------------------------------ +VIEW *calendar-view* + +This application has some different views. You can switch views with |>| and +|<| keys. Refer to |g:calendar_views| for the default views. + +1. Year view *calendar-view-year* + This view shows the months. If the window is not wide enough to view + all the months in the year, it shows the nearest 3 or 5 months. + The name of the year view is 'year'. + +2. Month view *calendar-view-month* + This view shows one month. This is the initial view on default. + The name of the month view is 'month'. + +3. Week view *calendar-view-week* + This view shows 7 days. + The name of the week view is 'week'. + +4. Days view *calendar-view-days* + This view shows 4 days on default. + The available days views are: 'day_7', 'day_6', 'day_5', 'day_4', + 'day_3', 'day_2', 'day_1' and 'weekday'. + + +5. Day view *calendar-view-day* + This view shows 1 day. + The name of the day view is 'day'. + +6. Clock view *calendar-view-clock* + This view shows a digital clock. + The name of the clock view is 'clock'. + +7. Event view *calendar-view-event* + This view shows a event list. There are two available event views: + 'event' and 'agenda'. + +------------------------------------------------------------------------------ +KEY MAPPINGS *calendar-key-mappings* + +This application provides a global mapping. +(calendar) *(calendar)* + Open a calendar buffer. This mapping calls the |:Calendar| command + with no argument. + +In the calendar buffer, a lot of mappings are provided. +This application has many views. Thus pressing j triggers various actions +based on the active window. For example, go to 7 days after in the month view, +go to the below month in the year view, 1 hour after in the week and day views, +and the next task in the task window. So the following mappings change its +behavior conformably in each views. + +Normal mode key mappings. + +Mappings for moving around. +(calendar_left) *(calendar_left)* +(calendar_right) *(calendar_right)* +(calendar_down) *(calendar_down)* +(calendar_up) *(calendar_up)* +(calendar_prev) *(calendar_prev)* +(calendar_next) *(calendar_next)* +(calendar_move_down) *(calendar_move_down)* +(calendar_move_up) *(calendar_move_up)* +(calendar_move_event) *(calendar_move_event)* +(calendar_down_big) *(calendar_down_big)* +(calendar_up_big) *(calendar_up_big)* +(calendar_down_large) *(calendar_down_large)* +(calendar_up_large) *(calendar_up_large)* +(calendar_line_head) *(calendar_line_head)* +(calendar_line_middle) *(calendar_line_middle)* +(calendar_line_last) *(calendar_line_last)* +(calendar_bar) *(calendar_bar)* +(calendar_first_line) *(calendar_first_line)* +(calendar_last_line) *(calendar_last_line)* +(calendar_first_line_head) *(calendar_first_line_head)* +(calendar_last_line_last) *(calendar_last_line_last)* + +Mappings for scrolling +(calendar_scroll_down) *(calendar_scroll_down)* +(calendar_scroll_up) *(calendar_scroll_up)* +(calendar_scroll_top_head) *(calendar_scroll_top_head)* +(calendar_scroll_top) *(calendar_scroll_top)* +(calendar_scroll_center_head) *(calendar_scroll_center_head)* +(calendar_scroll_center) *(calendar_scroll_center)* +(calendar_scroll_bottom_head) *(calendar_scroll_bottom_head)* +(calendar_scroll_bottom) *(calendar_scroll_bottom)* + +Utility +(calendar_add) *(calendar_add)* +(calendar_subtract) *(calendar_subtract)* +(calendar_status) *(calendar_status)* +(calendar_plus) *(calendar_plus)* +(calendar_minus) *(calendar_minus)* +(calendar_task) *(calendar_task)* +(calendar_event) *(calendar_event)* +(calendar_close_task) *(calendar_close_task)* +(calendar_close_event) *(calendar_close_event)* +(calendar_delete) *(calendar_delete)* +(calendar_delete_line) *(calendar_delete_line)* +(calendar_yank) *(calendar_yank)* +(calendar_yank_line) *(calendar_yank_line)* +(calendar_change) *(calendar_change)* +(calendar_change_line) *(calendar_change_line)* +(calendar_undo) *(calendar_undo)* +(calendar_undo_line) *(calendar_undo_line)* +(calendar_tab) *(calendar_tab)* +(calendar_shift_tab) *(calendar_shift_tab)* +(calendar_next_match) *(calendar_next_match)* +(calendar_prev_match) *(calendar_prev_match)* +(calendar_today) *(calendar_today)* +(calendar_enter) *(calendar_enter)* +(calendar_view_left) *(calendar_view_left)* +(calendar_view_right) *(calendar_view_right)* +(calendar_redraw) *(calendar_redraw)* +(calendar_clear) *(calendar_clear)* +(calendar_help) *(calendar_help)* +(calendar_escape) *(calendar_escape)* +(calendar_hide) *(calendar_hide)* +(calendar_exit) *(calendar_exit)* + +Insert mode +(calendar_start_insert) *(calendar_start_insert)* +(calendar_start_insert_append) *(calendar_start_insert_append)* +(calendar_start_insert_head) *(calendar_start_insert_head)* +(calendar_start_insert_last) *(calendar_start_insert_last)* +(calendar_start_insert_prev_line) *(calendar_start_insert_prev_line)* +(calendar_start_insert_next_line) *(calendar_start_insert_next_line)* +(calendar_start_insert_quick) *(calendar_start_insert_quick)* + +Visual mode +(calendar_visual) *(calendar_visual)* +(calendar_visual_line) *(calendar_visual_line)* +(calendar_visual_block) *(calendar_visual_block)* +(calendar_exit_visual) *(calendar_exit_visual)* + +Normal mode default mappings. +{lhs} {rhs} +-------- --------------------------------------- +h |(calendar_left)| +l |(calendar_right)| +j |(calendar_down)| +k |(calendar_up)| + |(calendar_left)| + |(calendar_right)| + |(calendar_down)| + |(calendar_up)| + same as h + same as h +gh same as h +gl same as l +gj same as j +gk same as k +g same as +g same as +g same as +g same as + same as + same as + |(calendar_move_down)| + |(calendar_move_up)| + |(calendar_move_down)| + |(calendar_move_up)| +M |(calendar_move_event)| +w |(calendar_next)| +W same as w +e same as w + same as w + same as w +b |(calendar_prev)| +B same as b +ge same as b +gE same as b + same as b + same as b + |(calendar_down)| + |(calendar_up)| + |(calendar_down_big)| + same as + |(calendar_up_big)| + same as + |(calendar_down_large)| + |(calendar_up_large)| + same as + same as +0 |(calendar_line_head)| +^ same as 0 +g0 same as 0 + same as 0 +g same as 0 +g^ same as ^ +gm |(calendar_line_middle)| +$ |(calendar_line_last)| +g$ same as $ +g_ same as $ + same as $ +g same as $ +gg |(calendar_first_line)| + same as gg +( |(calendar_first_line)| +{ same as ( +[[ same as ( +[] same as [[ +G |(calendar_last_line)| +) |(calendar_last_line)| +} same as ) +]] same as ) +][ same as ]] + |(calendar_last_line_last)| + |(calendar_bar)| + |(calendar_scroll_down)| + |(calendar_scroll_up)| +z |(calendar_scroll_top_head)| +zt |(calendar_scroll_top)| +z. |(calendar_scroll_center_head)| +zz |(calendar_scroll_center)| +z- |(calendar_scroll_bottom_head)| +zb |(calendar_scroll_bottom)| +d |(calendar_delete)| +D |(calendar_delete_line)| +y |(calendar_yank)| +Y |(calendar_yank_line)| +c |(calendar_change)| +C |(calendar_change_line)| + |(calendar_undo)| +u |(calendar_undo)| +U |(calendar_undo_line)| + |(calendar_tab)| + |(calendar_shift_tab)| +n |(calendar_next_match)| +N |(calendar_prev_match)| +t |(calendar_today)| + |(calendar_enter)| + |(calendar_add)| + |(calendar_subtract)| + |(calendar_status)| ++ |(calendar_plus)| +- |(calendar_minus)| +T |(calendar_task)| +E |(calendar_event)| +< |(calendar_view_left)| +> |(calendar_view_right)| + |(calendar_space)| + |(calendar_redraw)| + |(calendar_redraw)| +L |(calendar_clear)| +? |(calendar_help)| +q |(calendar_hide)| +Q |(calendar_exit)| +i |(calendar_start_insert)| +a |(calendar_start_insert_append)| +I |(calendar_start_insert_head)| +A |(calendar_start_insert_last)| +O |(calendar_start_insert_prev_line)| +o |(calendar_start_insert_next_line)| +v |(calendar_visual)| +V |(calendar_visual_line)| + |(calendar_visual_block)| +gh same as v +gH same as V +g same as + |(calendar_escape)| + +You can configure the mappings in the calendar buffers. +Example configuration: > + augroup calendar-mappings + autocmd! + + " diamond cursor + autocmd FileType calendar nmap i (calendar_up) + autocmd FileType calendar nmap j (calendar_left) + autocmd FileType calendar nmap k (calendar_down) + autocmd FileType calendar nmap l (calendar_right) + + " swap v and V + autocmd FileType calendar nmap V (calendar_visual) + autocmd FileType calendar nmap v (calendar_visual_line) + + " unmap , for other plugins + autocmd FileType calendar nunmap + autocmd FileType calendar nunmap + augroup END +< +------------------------------------------------------------------------------ +MARKS *calendar-marks* +In the |calendar| buffer, you can use |mark|s. + +m{a-z} Set mark {a-z} at the selected day and time. +:ma[rk] {a-z} Set mark {a-z} at the selected day and time. +:k{a-z} Same as :mark. +'{a-z} `{a-z} Jump to the mark {a-z}. +g'{a-z} g`{a-z} Jump to the mark {a-z}. +'' `` Jump to the latest mark. +:marks List all the marks. +:delm[arks] {mark} Delete the specified mark. +:delm[arks]! Delete all the marks. + +------------------------------------------------------------------------------ +INPUT FORMAT *calendar-input-format* +This application has some special format for user's input of events and tasks. + +Calendar: + Day event: + EVENT: [event-title] + + Few hours event: + EVENT: HH:MM - HH:MM [event-title] + EVENT: HH:MM:ss - HH:MM:ss [event-title] + + Example: + EVENT: 12:00 - 14:00 [event-title] + EVENT: 12:00:30 - 14:00:20 [event-title] + + Few days event: + EVENT: mm/dd [event-title] (all day event) + EVENT: mm/dd - mm/dd [event-title] + EVENT: yyyy/mm/dd - yyyy/mm/dd [event-title] (big endian) + EVENT: mm/dd/yyyy - mm/dd/yyyy [event-title] (middle endian) + EVENT: dd/mm/yyyy - dd/mm/yyyy [event-title] (little endian) + EVENT: yyyy-mm-dd - yyyy-mm-dd [event-title] (big endian, "-" separator) + + Example: + EVENT: 10/23 [event-title] (all day event) + EVENT: 10/23 - 10/25 [event-title] + EVENT: 2014/10/23 - 2014/10/25 [event-title] (big endian) + EVENT: 10/23/2014 - 10/25/2014 [event-title] (middle endian) + EVENT: 23/10/2014 - 25/10/2014 [event-title] (little endian) + EVENT: 2014-10-23 - 2014-10-25 [event-title] (big endian, "-" separator) + + Days and hours event: + EVENT: mm/dd HH:MM - mm/dd HH:MM [event-title] + EVENT: yyyy/mm/dd HH:MM - yyyy/mm/dd HH:MM [event-title] + EVENT: dd/mm/yyyy HH:MM - dd/mm/yyyy HH:MM [event-title] (little endian) + EVENT: dd-mm-yyyy HH:MM - dd-mm-yyyy HH:MM [event-title] (little endian, "-" separator) + + Example: + EVENT: 10/23 19:00 - 10/25 21:00 [event-title] + EVENT: 2014/10/23 19:00 - 2014/10/25 21:00 [event-title] + EVENT: 23-10-2014 10:00 - 25-10-2014 21:00 [event-title] (little endian, "-" separator) + +Task: + Simple task: + TASK: [task-title] + + Task with note: + TASK: [task-title] note: [task-note] + + Task with due date: + TASK: mm/dd [task-title] + TASK: mm-dd [task-title] + TASK: yyyy/mm/dd [task-title] + TASK: yyyy-mm-dd [task-title] + + Example: + TASK: 10/23 [task-title] + TASK: 10-23 [task-title] + TASK: 2014/10/23 [task-title] + TASK: 2014-10-23 [task-title] + + Task with due date and note: + TASK: yyyy/mm/dd [task-title] note: [task-note] + TASK: yyyy-mm-dd [task-title] note: [task-note] + + Example: + TASK: 2014/10/23 [task-title] note: [task-note] + TASK: 2014-10-23 [task-title] note: [task-note] + +------------------------------------------------------------------------------ +TROUBLESHOOTING *calendar-troubleshooting* + +Problem 1: |calendar-problem-1| + How to install this application. + +Problem 2: |calendar-problem-2| + How to update this application. + +Problem 3: |calendar-problem-3| + How to uninstall this application. + +Problem 4: |calendar-problem-4| + How to change key-mapping settings for calendar buffers. + +Problem 5: |calendar-problem-5| + The frame collapses (on Ubuntu). + +Problem 6: |calendar-problem-6| + The clock is invisible / The calendar is not colorful. + +Problem 7: |calendar-problem-7| + How to change the cache directory. + +Problem 8: |calendar-problem-8| + The clock stops to update after the cursor gets out of the window. + +Problem 9: |calendar-problem-9| + How to connect to Google Calendar / Google Task. + How to disconnect my Google account. + +Problem 10: |calendar-problem-10| + Authorization to Google fails again and again. + +Problem 11: |calendar-problem-11| + Which should we use, arguments or global variables. + +Problem 12: |calendar-problem-12| + Found a bug of this application. + Got many errors while using this application. + Vim hangs up while using this application. + Need a new mapping. + Want this application to be more configurable. + This troubleshooting is not helpful. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +Problem 1: *calendar-problem-1* + How to install this application. + + If you are to install this application manually: + + 1. Put all the files under $VIM. + + If you are using |vim-pathogen|, install this application with the + following command. +> + git clone https://github.com/itchyny/calendar.vim \ + ~/.vim/bundle/calendar.vim +< + If you are to install this application using |Vundle|: + + 1. Add the following configuration to your vimrc. +> + Plugin 'itchyny/calendar.vim' +< + 2. Install with |:PluginInstall|. + + If you are to install this application using |NeoBundle|: + + 1. Add the following configuration to your vimrc. +> + NeoBundle 'itchyny/calendar.vim' +< + 2. Install with |:NeoBundleInstall|. + +Problem 2: *calendar-problem-2* + How to update this application. + + If you have installed this application manually: + + 1. Access https://github.com/itchyny/calendar.vim . + 2. Download the latest scripts. + 3. Place the scripts as written in Problem 1. + + If you have installed this application with git clone command: + + 1. Update the application with git pull. + + If you have installed this application using Vundle: + + 1. Execute |:PluginInstall!|. Or try git pull in the + directory of this application. + + If you have installed this application using NeoBundle: + + 1. Execute |:NeoBundleInstall!|. Or try git pull in + the directory of this application. + +Problem 3: *calendar-problem-3* + How to uninstall this application. + + If you have installed this application manually or git clone + commend: + + 1. Remove all the related files under $VIM. + + If you have installed this application using Vundle: + + 1. Remove the :Plugin 'itchyny/calendar.vim' + configuration from your vimrc. + 2. Update with |:PluginClean|. + + If you have installed this application using NeoBundle: + + 1. Remove the :NeoBundle 'itchyny/calendar.vim' + configuration from your vimrc. + 2. Update with |:NeoBundleClean|. + +Problem 4: *calendar-problem-4* + How to change key-mapping settings for calendar buffers. + + Add the following configuration to your vimrc. > + augroup calendar-mappings + autocmd! + autocmd FileType calendar nmap {key} + \ (calendar_...) + autocmd FileType calendar nunmap {key} + augroup END +< + Example configuration: > + augroup calendar-mappings + autocmd! + + " diamond cursor + autocmd FileType calendar nmap i (calendar_up) + autocmd FileType calendar nmap j (calendar_left) + autocmd FileType calendar nmap k (calendar_down) + autocmd FileType calendar nmap l (calendar_right) + + " swap v and V + autocmd FileType calendar nmap V (calendar_visual) + autocmd FileType calendar nmap v (calendar_visual_line) + + " unmap , for other plugins + autocmd FileType calendar nunmap + autocmd FileType calendar nunmap + augroup END +< +Problem 5: *calendar-problem-5* + The frame collapses (on Ubuntu). + + Add the following configuration to your vimrc. > + let g:calendar_frame = 'default' + +Problem 6: *calendar-problem-6* + The clock is invisible / The calendar is not colorful. + + Add the following configuration to your *shrc (e.g. zshrc) > + export TERM=xterm-256color +< and add the following configuration to your vimrc. > + if !has('gui_running') + set t_Co=256 + endif +< +Problem 7: *calendar-problem-7* + How to change the cache directory. + + For example, add the following configuration to your vimrc. > + let g:calendar_cache_directory = expand('~/.vim/cache/calendar.vim/') +< See |g:calendar_cache_directory|. + +Problem 8: *calendar-problem-8* + The clock stops to update after the cursor gets out of the window. + + It is feature. Updating a specific buffer from other window + causes many problems. + +Problem 9: *calendar-problem-9* + How to connect to Google Calendar / Google Task. + How to disconnect my Google account. + + Add the following configuration to your vimrc. > + let g:calendar_google_calendar = 1 + let g:calendar_google_task = 1 +< See |g:calendar_google_calendar|, |g:calendar_google_task|. + + To disconnect, remove the cache directory. On default, the + cache directory is ~/.cache/calendar.vim/. So execute the + following command. > + rm -rf ~/.cache/calendar.vim/google/ +< See |g:calendar_cache_directory|. + +Problem 10: *calendar-problem-10* + Authorization to Google fails again and again. + + Remove the cache directory and reauthorize to Google. > + rm -rf ~/.cache/calendar.vim/google/ +< See |g:calendar_cache_directory|. + +Problem 11: *calendar-problem-11* + Which should we use, arguments or global variables. + + Arguments have priority over global variables. For example, if + you write > + let g:calendar_first_day = 'monday' +< the calendar opens with Monday as the first day. However, in + this situation, if you open the calendar with > + :Calendar -first_day=sunday +< Sunday is the first day. So you can write the comfortable + settings in your vimrc file and give the arguments in order to + overwrite the settings. + +Problem 12: *calendar-problem-12* + Found a bug of this application. + Got many errors while using this application. + Vim hangs up while using this application. + Need a new mapping. + Want this application to be more configurable. + This troubleshooting is not helpful. + + Report/Request the issue/feature at + https://github.com/itchyny/calendar.vim/issues + +============================================================================== +CHANGELOG *calendar-changelog* + +0.0 2014-01-05, ... + - Initial commit and implementation. + + 2013-06-22, ... + - Research and implementation. + +============================================================================== +vim:tw=78:sw=4:ts=8:ft=help:norl:noet: diff --git a/bundle/calendar.vim/plugin/calendar.vim b/bundle/calendar.vim/plugin/calendar.vim new file mode 100644 index 000000000..98dcb46cf --- /dev/null +++ b/bundle/calendar.vim/plugin/calendar.vim @@ -0,0 +1,25 @@ +" ============================================================================= +" Filename: plugin/calendar.vim +" Author: itchyny +" License: MIT License +" Last Change: 2016/11/06 12:00:00. +" ============================================================================= + +if exists('g:loaded_calendar') || v:version < 703 + finish +endif +let g:loaded_calendar = 1 + +let s:save_cpo = &cpo +set cpo&vim + +" :Calendar command +command! -nargs=* -complete=customlist,calendar#argument#complete + \ Calendar call calendar#new() + +" (calendar) +nnoremap (calendar) :Calendar +vnoremap (calendar) :Calendar + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/syntax/calendar.vim b/bundle/calendar.vim/syntax/calendar.vim new file mode 100644 index 000000000..6a5eb9cfc --- /dev/null +++ b/bundle/calendar.vim/syntax/calendar.vim @@ -0,0 +1,103 @@ +" ============================================================================= +" Filename: syntax/calendar.vim +" Author: itchyny +" License: MIT License +" Last Change: 2019/07/30 22:38:01. +" ============================================================================= + +if version < 700 + syntax clear +elseif exists('b:current_syntax') + finish +endif + +let s:save_cpo = &cpo +set cpo&vim + +let s:is_gui = has('gui_running') || (has('termguicolors') && &termguicolors) +let s:fg_color = calendar#color#normal_fg_color() +let s:bg_color = calendar#color#normal_bg_color() +let s:comment_fg_color = calendar#color#comment_fg_color() +let s:select_color = calendar#color#gen_color(s:fg_color, s:bg_color, 1, 4) +let s:space_fg_color = calendar#color#gen_color(s:fg_color, s:bg_color, 0, 1) +let s:space_bg_color = calendar#color#gen_color(s:fg_color, s:bg_color, 1, 0) +let s:is_win32cui = has('win32') && !s:is_gui +let s:is_dark = calendar#color#is_dark() + +if !s:is_gui + if s:is_win32cui + if s:is_dark + let s:select_color = 8 + let s:today_color = 10 + let s:today_fg_color = 0 + let s:othermonth_fg_color = 8 + else + let s:select_color = 7 + let s:today_color = 2 + let s:today_fg_color = 15 + let s:othermonth_fg_color = 7 + endif + let s:weekday_color = 8 + let s:weekday_fg_color = 0 + let s:sunday_bg_color = 12 + let s:saturday_bg_color = 9 + let s:sunday_fg_color = 0 + let s:saturday_fg_color = 0 + let s:sunday_title_fg_color = s:sunday_fg_color + let s:saturday_title_fg_color = s:saturday_fg_color + elseif s:is_dark + let s:sunday_bg_color = calendar#color#select_rgb(s:fg_color, 0, 5) + let s:saturday_bg_color = calendar#color#select_rgb(s:fg_color, 2, 5) + let s:sunday_fg_color = calendar#color#gen_color(s:sunday_bg_color, s:bg_color, 1, 7) + let s:saturday_fg_color = calendar#color#gen_color(s:saturday_bg_color, s:bg_color, 1, 7) + let s:today_color = calendar#color#select_rgb(s:fg_color, 1, 5) + let s:today_fg_color = calendar#color#gen_color(s:today_color, s:bg_color, 1, 5) + else + let s:sunday_fg_color = calendar#color#select_rgb(s:bg_color, 0, 6) + let s:saturday_fg_color = calendar#color#select_rgb(s:bg_color, 2, 6) + let s:sunday_bg_color = calendar#color#gen_color(s:sunday_fg_color, s:bg_color, 1, 4) + let s:saturday_bg_color = calendar#color#gen_color(s:saturday_fg_color, s:bg_color, 1, 4) + let s:today_fg_color = calendar#color#gen_color(calendar#color#select_rgb(s:fg_color, 1, 6), s:fg_color, 4, 3) + let s:today_color = calendar#color#gen_color(s:today_fg_color, s:bg_color, 1, 3) + endif +else + let s:sunday_fg_color = calendar#color#select_rgb(s:is_dark ? s:fg_color : s:bg_color, 1) + let s:saturday_fg_color = calendar#color#select_rgb(s:is_dark ? s:fg_color : s:bg_color, 4) + let s:sunday_bg_color = calendar#color#gen_color(s:sunday_fg_color, s:is_dark ? s:fg_color : s:bg_color, 1, 3) + let s:saturday_bg_color = calendar#color#gen_color(s:saturday_fg_color, s:is_dark ? s:fg_color : s:bg_color, 1, 3) + let s:today_fg_color = calendar#color#gen_color(calendar#color#select_rgb(s:is_dark ? s:fg_color : s:bg_color, 2), s:is_dark ? s:bg_color : s:fg_color, 4, 3) + let s:today_color = calendar#color#gen_color(s:today_fg_color, s:is_dark ? s:fg_color : s:bg_color, 1, 3) +endif +if !s:is_win32cui + let s:weekday_color = calendar#color#gen_color(s:fg_color, s:bg_color, 1, 5) + let s:weekday_fg_color = calendar#color#gen_color(s:fg_color, s:bg_color, 3, 2) + let s:othermonth_fg_color = calendar#color#gen_color(s:fg_color, s:bg_color, 3, 4) + let s:sunday_title_fg_color = calendar#color#gen_color(s:sunday_fg_color, s:sunday_bg_color, 3, 1) + let s:saturday_title_fg_color = calendar#color#gen_color(s:saturday_fg_color, s:saturday_bg_color, 3, 1) +endif + +call calendar#color#syntax('Select', '', s:select_color, '') +call calendar#color#syntax('Sunday', s:sunday_fg_color, s:sunday_bg_color, '') +call calendar#color#syntax('Saturday', s:saturday_fg_color, s:saturday_bg_color, '') +call calendar#color#syntax('TodaySunday', s:sunday_fg_color, s:sunday_bg_color, 'bold') +call calendar#color#syntax('TodaySaturday', s:saturday_fg_color, s:saturday_bg_color, 'bold') +call calendar#color#syntax('Today', s:today_fg_color, s:today_color, 'bold') +call calendar#color#syntax('DayTitle', s:weekday_fg_color, s:weekday_color, '') +call calendar#color#syntax('SundayTitle', s:sunday_title_fg_color, s:sunday_bg_color, '') +call calendar#color#syntax('SaturdayTitle', s:saturday_title_fg_color, s:saturday_bg_color, '') +call calendar#color#syntax('OtherMonth', s:othermonth_fg_color, '', '') +call calendar#color#syntax('OtherMonthSelect', s:othermonth_fg_color, s:select_color, '') +call calendar#color#syntax('NormalSpace', s:space_fg_color, s:space_bg_color, '') +call calendar#color#syntax('CommentSelect', s:comment_fg_color, s:select_color, '') + +highlight link CalendarComment Comment + +unlet! s:fg_color s:bg_color s:comment_fg_color s:select_color s:space_fg_color s:space_bg_color s:is_win32cui s:is_dark + \ s:today_color s:today_fg_color s:othermonth_fg_color s:weekday_color s:weekday_fg_color + \ s:sunday_bg_color s:sunday_fg_color s:sunday_title_fg_color + \ s:saturday_bg_color s:saturday_fg_color s:saturday_title_fg_color + +let b:current_syntax = 'calendar' + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/bundle/calendar.vim/test/cipher.vim b/bundle/calendar.vim/test/cipher.vim new file mode 100644 index 000000000..c86b25845 --- /dev/null +++ b/bundle/calendar.vim/test/cipher.vim @@ -0,0 +1,58 @@ +let s:suite = themis#suite('cipher') +let s:assert = themis#helper('assert') + +function! s:suite.cipher_string() + call s:assert.equals(calendar#cipher#cipher('', 0), '') + call s:assert.equals(calendar#cipher#cipher('', 100), '') + call s:assert.equals(calendar#cipher#cipher('ABCDEabcde012345!#%+,-/@[]', 0), 'ABCDEabcde012345!#%+,-/@[]') + call s:assert.equals(calendar#cipher#cipher('ABCDEabcde012345!#%+,-/@[]', 100), 'FGHIJfghij56789:&(*0124E`b') +endfunction + +function! s:suite.cipher_number() + call s:assert.equals(calendar#cipher#cipher(0, 0), '0') + call s:assert.equals(calendar#cipher#cipher(0, 100), '5') + call s:assert.equals(calendar#cipher#cipher(16777216, 0), '16777216') + call s:assert.equals(calendar#cipher#cipher(16777216, 100), '6;<<<76;') +endfunction + +function! s:suite.cipher_array() + call s:assert.equals(calendar#cipher#cipher([], 0), []) + call s:assert.equals(calendar#cipher#cipher([0, 1, 2], 0), ['0', '1', '2']) + call s:assert.equals(calendar#cipher#cipher([0, 1, 2], 100), ['5', '6', '7']) + call s:assert.equals(calendar#cipher#cipher(['65536', '16777216', '4294967296'], 100), [';::8;', '6;<<<76;', '97>9>;<7>;']) +endfunction + +function! s:suite.cipher_object() + call s:assert.equals(calendar#cipher#cipher({}, 100), {}) + call s:assert.equals(calendar#cipher#cipher( + \ { 'foo': [ '0', { 'bar': 16777216 }, [] ], 'bar': { 'baz': 'qux' }, 'quux': 'qux' }, 100), + \ { 'foo': [ '5', { 'bar': '6;<<<76;' }, [] ], 'bar': { 'baz': 'vz}' }, 'quux': 'vz}' }) +endfunction + +function! s:suite.decipher_string() + call s:assert.equals(calendar#cipher#decipher('', 0), '') + call s:assert.equals(calendar#cipher#decipher('', 100), '') + call s:assert.equals(calendar#cipher#decipher('ABCDEabcde012345!#%+,-/@[]', 0), 'ABCDEabcde012345!#%+,-/@[]') + call s:assert.equals(calendar#cipher#decipher('FGHIJfghij56789:&(*0124E`b', 100), 'ABCDEabcde012345!#%+,-/@[]') +endfunction + +function! s:suite.decipher_number() + call s:assert.equals(calendar#cipher#decipher('0', 0), 0) + call s:assert.equals(calendar#cipher#decipher('5', 100), 0) + call s:assert.equals(calendar#cipher#decipher('16777216', 0), 16777216) + call s:assert.equals(calendar#cipher#decipher('6;<<<76;', 100), 16777216) +endfunction + +function! s:suite.decipher_array() + call s:assert.equals(calendar#cipher#decipher([], 0), []) + call s:assert.equals(calendar#cipher#decipher(['0', '1', '2'], 0), ['0', '1', '2']) + call s:assert.equals(calendar#cipher#decipher(['5', '6', '7'], 100), ['0', '1', '2']) + call s:assert.equals(calendar#cipher#decipher([';::8;', '6;<<<76;', '97>9>;<7>;'], 100), ['65536', '16777216', '4294967296']) +endfunction + +function! s:suite.decipher_object() + call s:assert.equals(calendar#cipher#decipher({}, 100), {}) + call s:assert.equals(calendar#cipher#decipher( + \ { 'foo': [ '5', { 'bar': '6;<<<76;' }, [] ], 'bar': { 'baz': 'vz}' }, 'quux': 'vz}' }, 100), + \ { 'foo': [ '0', { 'bar': '16777216' }, [] ], 'bar': { 'baz': 'qux' }, 'quux': 'qux' }) +endfunction diff --git a/bundle/calendar.vim/test/day.vim b/bundle/calendar.vim/test/day.vim new file mode 100644 index 000000000..7fdcee030 --- /dev/null +++ b/bundle/calendar.vim/test/day.vim @@ -0,0 +1,132 @@ +let s:suite = themis#suite('day') +let s:assert = themis#helper('assert') + +function! s:suite.gregorian() + let tests = [ + \ [[2000, 1, 1], 51544, 6], + \ [[2020, 12, 31], 59214, 4], + \ [[2023, 1, 1], 59945, 0], + \ [[1858, 11, 17], 0, 3], + \ [[1600, 1, 1], -94553, 6], + \ [[1582, 10, 15], -100840, 5], + \ [[1580, 1, 1], -101858, 2], + \ ] + for test in tests + let [ymd, mjd, week] = test + let day = calendar#day#gregorian#new(ymd[0], ymd[1], ymd[2]) + call s:assert.equals(day.is_valid(), 1) + call s:assert.equals(day.get_ymd(), ymd) + call s:assert.equals(day.get_year(), ymd[0]) + call s:assert.equals(day.get_month(), ymd[1]) + call s:assert.equals(day.get_day(), ymd[2]) + call s:assert.equals(day.mjd, mjd) + call s:assert.equals(day.week(), week) + call s:assert.equals(day.year().get_year(), ymd[0]) + call s:assert.equals(day.month().get_year(), ymd[0]) + call s:assert.equals(day.month().get_month(), ymd[1]) + call s:assert.equals(day.is_gregorian(), 1) + endfor +endfunction + +function! s:suite.julian() + let tests = [ + \ [[2000, 1, 1], 51557, 5], + \ [[2020, 12, 31], 59227, 3], + \ [[2023, 1, 1], 59958, 6], + \ [[1858, 11, 17], 12, 1], + \ [[1600, 1, 1], -94543, 2], + \ [[1582, 10, 4], -100841, 4], + \ [[1580, 1, 1], -101848, 5], + \ ] + for test in tests + let [ymd, mjd, week] = test + let day = calendar#day#julian#new(ymd[0], ymd[1], ymd[2]) + call s:assert.equals(day.is_valid(), 1) + call s:assert.equals(day.get_ymd(), ymd) + call s:assert.equals(day.get_year(), ymd[0]) + call s:assert.equals(day.get_month(), ymd[1]) + call s:assert.equals(day.get_day(), ymd[2]) + call s:assert.equals(day.mjd, mjd) + call s:assert.equals(day.week(), week) + call s:assert.equals(day.year().get_year(), ymd[0]) + call s:assert.equals(day.month().get_year(), ymd[0]) + call s:assert.equals(day.month().get_month(), ymd[1]) + call s:assert.equals(day.is_gregorian(), 0) + endfor +endfunction + +function! s:suite.default() + let tests = [ + \ [[2000, 1, 1], 51544, 6, 1], + \ [[2020, 12, 31], 59214, 4, 1], + \ [[2023, 1, 1], 59945, 0, 1], + \ [[1858, 11, 17], 0, 3, 1], + \ [[1600, 1, 1], -94553, 6, 1], + \ [[1582, 10, 15], -100840, 5, 1], + \ [[1582, 10, 4], -100841, 4, 0], + \ [[1580, 1, 1], -101848, 5, 0], + \ ] + for test in tests + let [ymd, mjd, week, is_gregorian] = test + let day = calendar#day#default#new(ymd[0], ymd[1], ymd[2]) + call s:assert.equals(day.is_valid(), 1) + call s:assert.equals(day.get_ymd(), ymd) + call s:assert.equals(day.get_year(), ymd[0]) + call s:assert.equals(day.get_month(), ymd[1]) + call s:assert.equals(day.get_day(), ymd[2]) + call s:assert.equals(day.mjd, mjd) + call s:assert.equals(day.week(), week) + call s:assert.equals(day.year().get_year(), ymd[0]) + call s:assert.equals(day.month().get_year(), ymd[0]) + call s:assert.equals(day.month().get_month(), ymd[1]) + call s:assert.equals(day.is_gregorian(), is_gregorian) + endfor +endfunction + +function! s:suite.british() + let tests = [ + \ [[2000, 1, 1], 51544, 6, 1], + \ [[2020, 12, 31], 59214, 4, 1], + \ [[2023, 1, 1], 59945, 0, 1], + \ [[1858, 11, 17], 0, 3, 1], + \ [[1752, 9, 14], -38779, 4, 1], + \ [[1752, 9, 2], -38780, 3, 0], + \ [[1600, 1, 1], -94543, 2, 0], + \ [[1582, 10, 15], -100830, 1, 0], + \ [[1582, 10, 4], -100841, 4, 0], + \ [[1580, 1, 1], -101848, 5, 0], + \ ] + for test in tests + let [ymd, mjd, week, is_gregorian] = test + let day = calendar#day#british#new(ymd[0], ymd[1], ymd[2]) + call s:assert.equals(day.is_valid(), 1) + call s:assert.equals(day.get_ymd(), ymd) + call s:assert.equals(day.get_year(), ymd[0]) + call s:assert.equals(day.get_month(), ymd[1]) + call s:assert.equals(day.get_day(), ymd[2]) + call s:assert.equals(day.mjd, mjd) + call s:assert.equals(day.week(), week) + call s:assert.equals(day.year().get_year(), ymd[0]) + call s:assert.equals(day.month().get_year(), ymd[0]) + call s:assert.equals(day.month().get_month(), ymd[1]) + call s:assert.equals(day.is_gregorian(), is_gregorian) + endfor +endfunction + +function! s:suite.add_sub() + let tests = [ + \ [[2000, 1, 1], 1000, [2002, 9, 27]], + \ [[2020, 12, 31], -10000, [1993, 8, 15]], + \ [[1600, 1, 1], 1000000, [4337, 11, 28]], + \ [[1582, 10, 15], -1, [1582, 10, 4]], + \ [[1582, 10, 4], 1, [1582, 10, 15]], + \ [[1, 1, 1], 1000000, [2738, 11, 27]], + \ ] + for test in tests + let [ymd, diff, new_ymd] = test + let day = calendar#day#new(ymd[0], ymd[1], ymd[2]) + call s:assert.equals(day.add(diff).get_ymd(), new_ymd) + call s:assert.equals(day.sub(calendar#day#new(new_ymd[0], new_ymd[1], new_ymd[2])), -diff) + call s:assert.equals(calendar#day#new(new_ymd[0], new_ymd[1], new_ymd[2]).sub(day), diff) + endfor +endfunction diff --git a/bundle/calendar.vim/test/pixel.vim b/bundle/calendar.vim/test/pixel.vim new file mode 100644 index 000000000..1e91d0895 --- /dev/null +++ b/bundle/calendar.vim/test/pixel.vim @@ -0,0 +1,24 @@ +let s:suite = themis#suite('pixel') +let s:assert = themis#helper('assert') + +function! s:suite.pixel_get() + call s:assert.equals(calendar#pixel#get(''), ['', '', '', '', '']) + call s:assert.equals(calendar#pixel#get(':'), ['....', '.%%.', '....', '.%%.', '....']) + call s:assert.equals(calendar#pixel#get('0'), ['%%%%%%', '%%..%%', '%%..%%', '%%..%%', '%%%%%%']) + call s:assert.equals(calendar#pixel#get('1'), ['....%%', '....%%', '....%%', '....%%', '....%%']) + call s:assert.equals(calendar#pixel#get('8'), ['%%%%%%', '%%..%%', '%%%%%%', '%%..%%', '%%%%%%']) + call s:assert.equals(calendar#pixel#get('C'), ['.%%%%%.', '%%...%%', '%%.....', '%%...%%', '.%%%%%.']) + call s:assert.equals(calendar#pixel#get('E'), ['%%%%%%', '%%....', '%%%%%.', '%%....', '%%%%%%']) + call s:assert.equals(calendar#pixel#get('O'), ['.%%%%%.', '%%...%%', '%%...%%', '%%...%%', '.%%%%%.']) + call s:assert.equals(calendar#pixel#get('T'), ['%%%%%%%%', '...%%...', '...%%...', '...%%...', '...%%...']) +endfunction + +function! s:suite.pixel_len() + call s:assert.equals(calendar#pixel#len(''), 0) + call s:assert.equals(calendar#pixel#len(':'), 2) + call s:assert.equals(calendar#pixel#len('0'), 6) + call s:assert.equals(calendar#pixel#len('11'), 8) + call s:assert.equals(calendar#pixel#len('00'), 12) + call s:assert.equals(calendar#pixel#len('123'), 14) + call s:assert.equals(calendar#pixel#len('213'), 18) +endfunction diff --git a/bundle/calendar.vim/test/week.vim b/bundle/calendar.vim/test/week.vim new file mode 100644 index 000000000..f4c25afa9 --- /dev/null +++ b/bundle/calendar.vim/test/week.vim @@ -0,0 +1,106 @@ +let s:suite = themis#suite('week') +let s:assert = themis#helper('assert') + +function! s:suite.before_each() + language en_US.UTF-8 + unlet! g:calendar_first_day +endfunction + +function! s:suite.first_day_index() + call s:assert.equals(calendar#week#first_day_index(), 0) + let g:calendar_first_day = 'sunday' + call s:assert.equals(calendar#week#first_day_index(), 0) + let g:calendar_first_day = 'Monday' + call s:assert.equals(calendar#week#first_day_index(), 1) + let g:calendar_first_day = 'Tuesday' + call s:assert.equals(calendar#week#first_day_index(), 2) + let g:calendar_first_day = 'WEDNESDAY' + call s:assert.equals(calendar#week#first_day_index(), 3) + let g:calendar_first_day = 'thursday' + call s:assert.equals(calendar#week#first_day_index(), 4) + let g:calendar_first_day = 'friday' + call s:assert.equals(calendar#week#first_day_index(), 5) + let g:calendar_first_day = 'saturday' + call s:assert.equals(calendar#week#first_day_index(), 6) +endfunction + +function! s:suite.last_day_index() + call s:assert.equals(calendar#week#last_day_index(), 6) + let g:calendar_first_day = 'sunday' + call s:assert.equals(calendar#week#last_day_index(), 6) + let g:calendar_first_day = 'Monday' + call s:assert.equals(calendar#week#last_day_index(), 0) + let g:calendar_first_day = 'Tuesday' + call s:assert.equals(calendar#week#last_day_index(), 1) + let g:calendar_first_day = 'WEDNESDAY' + call s:assert.equals(calendar#week#last_day_index(), 2) + let g:calendar_first_day = 'thursday' + call s:assert.equals(calendar#week#last_day_index(), 3) + let g:calendar_first_day = 'friday' + call s:assert.equals(calendar#week#last_day_index(), 4) + let g:calendar_first_day = 'saturday' + call s:assert.equals(calendar#week#last_day_index(), 5) +endfunction + +function! s:suite.is_first_day() + call s:assert.equals(calendar#week#first_day_index(), 0) + call s:assert.equals(calendar#week#is_first_day(calendar#day#new(2000, 1, 1)), 0) + call s:assert.equals(calendar#week#is_first_day(calendar#day#new(2001, 1, 1)), 0) + call s:assert.equals(calendar#week#is_first_day(calendar#day#new(2004, 1, 1)), 0) + call s:assert.equals(calendar#week#is_first_day(calendar#day#new(2005, 1, 1)), 0) + call s:assert.equals(calendar#week#is_first_day(calendar#day#new(2006, 1, 1)), 1) + call s:assert.equals(calendar#week#is_first_day(calendar#day#new(2007, 1, 1)), 0) +endfunction + +function! s:suite.is_last_day() + call s:assert.equals(calendar#week#is_last_day(calendar#day#new(2000, 1, 1)), 1) + call s:assert.equals(calendar#week#is_last_day(calendar#day#new(2001, 1, 1)), 0) + call s:assert.equals(calendar#week#is_last_day(calendar#day#new(2004, 1, 1)), 0) + call s:assert.equals(calendar#week#is_last_day(calendar#day#new(2005, 1, 1)), 1) + call s:assert.equals(calendar#week#is_last_day(calendar#day#new(2006, 1, 1)), 0) + call s:assert.equals(calendar#week#is_last_day(calendar#day#new(2007, 1, 1)), 0) +endfunction + +function! s:suite.week_index() + call s:assert.equals(calendar#week#week_index(calendar#day#new(2000, 1, 1)), 6) + call s:assert.equals(calendar#week#week_index(calendar#day#new(2001, 1, 1)), 1) + call s:assert.equals(calendar#week#week_index(calendar#day#new(2004, 1, 1)), 4) + call s:assert.equals(calendar#week#week_index(calendar#day#new(2005, 1, 1)), 6) + call s:assert.equals(calendar#week#week_index(calendar#day#new(2006, 1, 1)), 0) + call s:assert.equals(calendar#week#week_index(calendar#day#new(2007, 1, 1)), 1) + let g:calendar_first_day = 'monday' + call s:assert.equals(calendar#week#week_index(calendar#day#new(2000, 1, 1)), 5) + call s:assert.equals(calendar#week#week_index(calendar#day#new(2001, 1, 1)), 0) + call s:assert.equals(calendar#week#week_index(calendar#day#new(2004, 1, 1)), 3) + call s:assert.equals(calendar#week#week_index(calendar#day#new(2005, 1, 1)), 5) + call s:assert.equals(calendar#week#week_index(calendar#day#new(2006, 1, 1)), 6) + call s:assert.equals(calendar#week#week_index(calendar#day#new(2007, 1, 1)), 0) + let g:calendar_first_day = 'saturday' + call s:assert.equals(calendar#week#week_index(calendar#day#new(2000, 1, 1)), 0) + call s:assert.equals(calendar#week#week_index(calendar#day#new(2001, 1, 1)), 2) + call s:assert.equals(calendar#week#week_index(calendar#day#new(2004, 1, 1)), 5) + call s:assert.equals(calendar#week#week_index(calendar#day#new(2005, 1, 1)), 0) + call s:assert.equals(calendar#week#week_index(calendar#day#new(2006, 1, 1)), 1) + call s:assert.equals(calendar#week#week_index(calendar#day#new(2007, 1, 1)), 2) +endfunction + +function! s:suite.week_number() + call s:assert.equals(calendar#week#week_number(calendar#day#new(2000, 1, 1)), 1) + call s:assert.equals(calendar#week#week_number(calendar#day#new(2001, 1, 1)), 1) + call s:assert.equals(calendar#week#week_number(calendar#day#new(2004, 1, 1)), 1) + call s:assert.equals(calendar#week#week_number(calendar#day#new(2005, 1, 1)), 1) + call s:assert.equals(calendar#week#week_number(calendar#day#new(2006, 1, 1)), 1) + call s:assert.equals(calendar#week#week_number(calendar#day#new(2007, 1, 1)), 1) + call s:assert.equals(calendar#week#week_number(calendar#day#new(2010, 12, 31)), 53) + call s:assert.equals(calendar#week#week_number(calendar#day#new(2020, 5, 9)), 19) + call s:assert.equals(calendar#week#week_number(calendar#day#new(2020, 5, 10)), 20) + let g:calendar_first_day = 'monday' + call s:assert.equals(calendar#week#week_number(calendar#day#new(2000, 1, 1)), 52) + call s:assert.equals(calendar#week#week_number(calendar#day#new(2001, 1, 1)), 1) + call s:assert.equals(calendar#week#week_number(calendar#day#new(2004, 1, 1)), 1) + call s:assert.equals(calendar#week#week_number(calendar#day#new(2005, 1, 1)), 53) + call s:assert.equals(calendar#week#week_number(calendar#day#new(2006, 1, 1)), 52) + call s:assert.equals(calendar#week#week_number(calendar#day#new(2007, 1, 1)), 1) + call s:assert.equals(calendar#week#week_number(calendar#day#new(2009, 1, 1)), 1) + call s:assert.equals(calendar#week#week_number(calendar#day#new(2010, 1, 1)), 53) +endfunction