Skip to content

Render images with image.nvim #115

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 19 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
__pycache__/
.venv/
40 changes: 38 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,16 @@ Example usage:
:MagmaShowOutput
```

#### MagmaHideOutput

This closes all currently open output windows

Example usage:

```vim
:MagmaHideOutput
```

#### MagmaInterrupt

Send a keyboard interrupt to the kernel. Interrupts the currently running cell and does nothing if not
Expand Down Expand Up @@ -273,13 +283,15 @@ If that parameter is omitted, then one will be automatically generated using the

#### MagmaEnterOutput

Enter the output window, if it is currently open. You must call this as follows:
Configured with [magma_enter_output_behavior](#gmagma_enter_output_behavior)

Enter/open the output window. You must call this as follows:

```vim
:noautocmd MagmaEnterOutput
```

This is escpecially useful when you have a long output (or errors) and wish to inspect it.
This is especially useful when you have a long output (or errors) and wish to inspect it.

## Keybindings

Expand All @@ -306,6 +318,14 @@ nnoremap <silent> <LocalLeader>rq :noautocmd MagmaEnterOutput<CR>

Customization is done via variables.

### `g:magma_enter_output_behavior`

Configures the behavior of [MagmaEnterOutput](#magmaenteroutput)

- `"open_then_enter"` (default) -- open the window if it's closed. Enter the window if it's already open
- `"open_and_enter"` -- open and enter the window if it's closed. Otherwise enter as normal
- `"no_open"` -- enter the window when it's open, do nothing if it's closed

### `g:magma_image_provider`

Defaults to `"none"`.
Expand Down Expand Up @@ -373,6 +393,22 @@ We provide some `User` autocommands (see `:help User`) for further customization
- `MagmaDeinitPre`: runs right before `MagmaDeinit` deinitialization happens for a buffer
- `MagmaDeinitPost`: runs right after `MagmaDeinit` deinitialization happens for a buffer

## Functions

There is a provided function `MagmaEvaluateRange(start_line, end_line)` which evaluates the code
between the given line numbers (inclusive). This is intended for use in scripts.

### Example Usage:
```lua
vim.fn.MagmaEvaluateRange(1, 23)
```

```vim
MagmaEvaluateRange(1, 23)
" from the command line
:call MagmaEvaluateRange(1, 23)
```

## Extras

### Output Chunks
Expand Down
60 changes: 60 additions & 0 deletions lua/load_image_nvim.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
-- loads the image.nvim plugin and exposes methods to the python remote plugin
local ok, image = pcall(require, "image")

if not ok then
vim.api.nvim_err_writeln("[Magma] `image.nvim` not found")
return
end

local image_api = {}
local images = {}
local utils = {}

image_api.from_file = function(path, opts)
images[path] = image.from_file(path, opts or {})
return path
end

image_api.render = function(identifier, geometry)
geometry = geometry or {}
local img = images[identifier]

-- a way to render images in windows when only their buffer is set
if img.buffer and not img.window then
local buf_win = vim.fn.getbufinfo(img.buffer)[1].windows
if #buf_win > 0 then img.window = buf_win[1] end
end

-- only render when the window is visible
if img.window and vim.api.nvim_win_is_valid(img.window) then
img:render(geometry)
end
end

image_api.clear = function(identifier)
images[identifier]:clear()
end

image_api.clear_all = function()
for _, img in pairs(images) do
img:clear()
end
end

image_api.move = function(identifier, x, y)
images[identifier]:move(x, y)
end

image_api.image_size = function(identifier)
local img = images[identifier]
return { width = img.image_width, height = img.image_height }
end

------ utils --------

utils.cell_size = function()
local size = require("image.utils.term").get_size()
return { width = size.cell_width, height = size.cell_height }
end

return { image_api = image_api, image_utils = utils }
85 changes: 58 additions & 27 deletions rplugin/python3/magma/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,25 +63,13 @@ def _initialize(self) -> None:

def _set_autocommands(self) -> None:
self.nvim.command("augroup magma")
self.nvim.command(
" autocmd CursorMoved * call MagmaUpdateInterface()"
)
self.nvim.command(
" autocmd CursorMovedI * call MagmaUpdateInterface()"
)
self.nvim.command(
" autocmd WinScrolled * call MagmaUpdateInterface()"
)
self.nvim.command(
" autocmd BufEnter * call MagmaUpdateInterface()"
)
self.nvim.command(
" autocmd BufLeave * call MagmaClearInterface()"
)
self.nvim.command(
" autocmd BufUnload * call MagmaOnBufferUnload()"
)
self.nvim.command(" autocmd ExitPre * call MagmaOnExitPre()")
self.nvim.command("autocmd CursorMoved * call MagmaOnCursorMoved()")
self.nvim.command("autocmd CursorMovedI * call MagmaOnCursorMoved()")
self.nvim.command("autocmd WinScrolled * call MagmaOnWinScrolled()")
self.nvim.command("autocmd BufEnter * call MagmaUpdateInterface()")
self.nvim.command("autocmd BufLeave * call MagmaClearInterface()")
self.nvim.command("autocmd BufUnload * call MagmaOnBufferUnload()")
self.nvim.command("autocmd ExitPre * call MagmaOnExitPre()")
self.nvim.command("augroup END")

def _deinitialize(self) -> None:
Expand Down Expand Up @@ -124,10 +112,20 @@ def _update_interface(self) -> None:

magma.update_interface()

def _on_cursor_moved(self, scrolled=False) -> None:
if not self.initialized:
return

magma = self._get_magma(False)
if magma is None:
return

magma.on_cursor_moved(scrolled)

def _ask_for_choice(
self, preface: str, options: List[str]
) -> Optional[str]:
index: int = self.nvim.funcs.inputlist(
index = self.nvim.funcs.inputlist(
[preface]
+ [f"{i+1}. {option}" for i, option in enumerate(options)]
)
Expand All @@ -152,7 +150,7 @@ def _initialize_buffer(self, kernel_name: str) -> MagmaBuffer:

return magma

@pynvim.command("MagmaInit", nargs="?", sync=True, complete='file') # type: ignore
@pynvim.command("MagmaInit", nargs="?", sync=True, complete="file") # type: ignore
@nvimui # type: ignore
def command_init(self, args: List[str]) -> None:
self._initialize_if_necessary()
Expand Down Expand Up @@ -267,13 +265,23 @@ def command_evaluate_visual(self) -> None:

self._do_evaluate(span)

@pynvim.function("MagmaEvaluateRange", sync=True) # type: ignore
@nvimui # type: ignore
def evaulate_range(self, *args) -> None:
# self.nvim.current.line = f"args: {args}"
start_line, end_line = args[0]
span = (
(start_line - 1, 0),
(end_line - 1, len(self.nvim.funcs.getline(end_line))),
)
self._do_evaluate(span)

@pynvim.command("MagmaEvaluateOperator", sync=True) # type: ignore
@nvimui # type: ignore
def command_evaluate_operator(self) -> None:
self._initialize_if_necessary()

self.nvim.options["operatorfunc"] = "MagmaOperatorfunc"
self.nvim.out_write("g@\n")

@pynvim.command("MagmaEvaluateLine", nargs=0, sync=True) # type: ignore
@nvimui # type: ignore
Expand Down Expand Up @@ -332,6 +340,15 @@ def command_show_output(self) -> None:
magma.should_open_display_window = True
self._update_interface()

@pynvim.command("MagmaHideOutput", nargs=0, sync=True) # type: ignore
@nvimui # type: ignore
def command_hide_output(self) -> None:
magma = self._get_magma(True)
assert magma is not None

magma.should_open_display_window = False
self._clear_interface()

@pynvim.command("MagmaSave", nargs="?", sync=True) # type: ignore
@nvimui # type: ignore
def command_save(self, args: List[str]) -> None:
Expand Down Expand Up @@ -436,9 +453,19 @@ def function_magma_tick(self, _: Any) -> None:
def function_update_interface(self, _: Any) -> None:
self._update_interface()

@pynvim.function("MagmaOperatorfunc", sync=True) # type: ignore
@nvimui # type: ignore
def function_magma_operatorfunc(self, args: List[str]) -> None:
@pynvim.function("MagmaOnCursorMoved", sync=True)
@nvimui
def function_on_cursor_moved(self, _) -> None:
self._on_cursor_moved()

@pynvim.function("MagmaOnWinScrolled", sync=True)
@nvimui
def function_on_win_scrolled(self, _) -> None:
self._on_cursor_moved(scrolled=True)

@pynvim.function("MagmaOperatorfunc", sync=True)
@nvimui
def function_magma_operatorfunc(self, args) -> None:
if not args:
return

Expand Down Expand Up @@ -487,6 +514,10 @@ def function_magma_define_cell(self, args: List[int]) -> None:
DynamicPosition(
self.nvim, self.extmark_namespace, bufno, start - 1, 0
),
DynamicPosition(self.nvim, self.extmark_namespace, bufno, end - 1, -1),
DynamicPosition(
self.nvim, self.extmark_namespace, bufno, end - 1, -1
),
)
magma.outputs[span] = OutputBuffer(
self.nvim, self.canvas, self.options
)
magma.outputs[span] = OutputBuffer(self.nvim, self.canvas, self.options)
Loading