-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 730951a
Showing
2 changed files
with
159 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
# vim-jupycent | ||
|
||
Plugin for editing [Jupyter notebook][1] (ipynb) files via the [jupytext][2] | ||
percent format. | ||
|
||
[jupytext.vim][3] is an excellent plugin, but it loads the result of the | ||
jupytext conversion into the ipynb buffer, which causes issues with other | ||
plugins for version control (e.g., gitgutter) and linting (e.g., coc.nvim). | ||
[jupytext.vim][3] is also a more flexible wrapper of jupytext, whereas | ||
vim-jupycent only converts to the python percent format, and adds some | ||
highlighting and folding based on this format. | ||
|
||
## Installation | ||
|
||
1. Make sure that you have the `jupytext` CLI program installed (`pip install jupytext`). | ||
2. Install this plugin with your favourite method, like vim-plug (`Plug 'gabenespoli/vim-jupycent'`). | ||
|
||
## Usage | ||
|
||
When you open a Jupyter Notebook (`*.ipynb`) file, it is automatically | ||
converted from json to markdown or python through the [`jupytext` utility][2], | ||
and the result is loaded into the buffer. Upon saving, the `ipynb` file is | ||
updated with any modifications. | ||
|
||
In more detail, opening a file `notebook.ipynb` in vim will create a temporary | ||
file `notebook.py`. This file is the result of calling e.g. | ||
|
||
jupytext --to=py:percent --output notebook.md notebook.ipynb | ||
|
||
The file `notebook.py` is opened, and the original `notebook.ipynb` is wiped | ||
from vim. When saving the buffer, its contents is first written to | ||
`notebook.py`, and then the original `notebook.ipynb` is updated with a call to | ||
|
||
jupytext --from=py:percent --to=ipynb --update --output notebook.ipynb notebook.py | ||
|
||
The `--update` flag ensures the output for any cell whose corresponding input | ||
in `notebook.py` is unchanged will be preserved. | ||
|
||
On closing the buffer, the temporary `notebook.py` will be deleted. If | ||
`notebook.py` already existed when opening `notebook.ipynb`, the existing file | ||
will be used (instead of being generated by `jupytext`), and it will be | ||
preserved when closing the buffer. | ||
|
||
## Configuration | ||
|
||
The plugin has the following settings. If you want to override the default values shown below, you can define the corresponding variables in your `~/.vimrc`. | ||
|
||
* `let g:jupytext_enable = 1` | ||
|
||
You may disable the automatic conversion of `ipynb` files (i.e., deactivate this plugin) by setting this to 0. | ||
|
||
* `let g:jupytext_command = 'jupytext'` | ||
|
||
The CLI `jupytext` command to use. You may include the full path to point to a specific `jupytext` executable not in your default `$PATH`. | ||
|
||
* `let g:jupytext_to_ipynb_opts = '--to=ipynb --update'` | ||
|
||
Command line options for the conversion from `g:jupytext_fmt` back to the notebook format | ||
|
||
## Acknowledgements | ||
|
||
This plugin takes some inspiration, code, and documentation from [jupytext.vim][3]. vim-jupycent is basically a fork of [jupytext.vim][3], but is probably too different to call it a fork. | ||
|
||
[1]: http://jupyter.org | ||
[2]: https://github.com/mwouts/jupytext | ||
[3]: https://github.com/goerz/jupytext.vim |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
if exists("loaded_jupycent") | ||
finish | ||
endif | ||
|
||
if !exists('g:jupycent_command') | ||
let g:jupycent_command = 'jupytext' | ||
endif | ||
|
||
if !exists('g:jupycent_enable') | ||
let g:jupycent_enable = 1 | ||
endif | ||
|
||
if !exists('g:jupycent_to_ipynb_opts') | ||
let g:jupycent_to_ipynb_opts = '--to=ipynb --update' | ||
endif | ||
|
||
if !g:jupycent_enable | ||
finish | ||
endif | ||
|
||
augroup jupycent_ipynb | ||
au! | ||
autocmd BufReadPost *.ipynb call s:read_from_ipynb() | ||
augroup END | ||
|
||
function! s:read_from_ipynb() | ||
if expand("<afile>:e") != "ipynb" | ||
echo "Not an ipynb file." | ||
return | ||
endif | ||
let l:filename = expand("%:p") | ||
let l:jupycent_file = fnamemodify(l:filename, ":r") . ".py" | ||
let l:jupycent_file_exists = filereadable(l:jupycent_file) | ||
if !filereadable(l:jupycent_file) | ||
let l:output = system(g:jupycent_command . " --to=py:percent " | ||
\ . "--output=" . shellescape(l:jupycent_file) . " " | ||
\ . shellescape(l:filename)) | ||
endif | ||
|
||
" open the jupytext py:percent file, wipe the ipynb file | ||
let l:bufnr = bufnr("%") | ||
execute "edit " . l:jupycent_file | ||
execute "bwipeout" . l:bufnr | ||
|
||
" set properties of the jupycent file buffer | ||
let b:jupycent_ipynb_file = l:filename | ||
set filetype=python | ||
setlocal foldmethod=expr | ||
setlocal foldexpr=JupycentFold(v:lnum) | ||
setlocal foldtext=getline(v:foldstart+1) | ||
syntax match JupycentCell /^#\ %%/ | ||
hi link JupycentCell FoldColumn | ||
execute "autocmd jupycent_ipynb BufWritePost,FileWritePost <buffer> call s:write_to_ipynb()" | ||
if !l:jupycent_file_exists | ||
execute "autocmd jupycent_ipynb BufUnload <buffer> call s:cleanup()" | ||
endif | ||
endfunction | ||
|
||
function! s:write_to_ipynb() abort | ||
if !exists("b:jupycent_ipynb_file") | ||
echo "Not a jupycent py file." | ||
return | ||
endif | ||
let l:jupycent_file = expand("<afile>:p") | ||
let l:output = system(g:jupycent_command . " --from=py:percent " | ||
\ . g:jupycent_to_ipynb_opts . " " | ||
\ . "--output " . shellescape(b:jupycent_ipynb_file) . " " | ||
\ . shellescape(l:jupycent_file)) | ||
echo b:jupycent_ipynb_file . " updated." | ||
endfunction | ||
|
||
function! s:cleanup() | ||
if !exists("b:jupycent_ipynb_file") | ||
echo "Not a jupycent py file." | ||
return | ||
endif | ||
call delete(expand("<afile>:p")) | ||
endfunction | ||
|
||
function! JupycentFold(lnum) | ||
let l:line = getline(a:lnum) | ||
if a:lnum <= 2 && l:line =~# '^#\ ---$' | ||
return '>1' | ||
elseif l:line =~# '^#\ %%$' | ||
return '>1' | ||
elseif l:line =~# '^#\ %% [markdown]$' | ||
return '>1' | ||
else | ||
return '=' | ||
endif | ||
endfunction | ||
|
||
let loaded_jupycent = 1 |