Vigemus / iron.nvim

Interactive Repl Over Neovim
BSD 3-Clause "New" or "Revised" License
1.02k stars 82 forks source link

MATLAB/Octave support? #236

Open krishnakumarg1984 opened 2 years ago

krishnakumarg1984 commented 2 years ago

Hi,

Does this support MATLAB/Octave? I am forced to use MATLAB in a recent project, and was looking for a suitable neovim REPL plugin.

agdestein commented 2 years ago

You can add a MATLAB entry to the list of repl_definitions:

matlab = {
    command = {
        "matlab",
        "-nosplash",
        "-nodesktop",
    },
}
hkupty commented 2 years ago

Hi! Thanks @agdestein for providing a snippet - I wouldn't know where to start to get matlab to work :)

@krishnakumarg1984 Let me know if this works and if you need further assistence.

Best regards, Henry

krishnakumarg1984 commented 2 years ago

Yes. While that works, there doesn't seem to be support for sending a demarcated block of code (called cells in MATLAB parlance) to the REPL.

The last time I used MATLAB was about 5 years ago, and there was a vim script plugin (https://github.com/daeyun/vim-matlab) that worked reasonably well to provide a REPL with the ability to execute cells etc. This is unmaintained currently, and I am looking for a generic REPL plugin that will work for my python, julia, bash and matlab projects.

Cell support (feature request)

Cells are code regions that begin with %% and end when another cell starting block is encountered or the end of file is reached. The built-in MATLAB editor (although pretty horrible) has support for "executing current cell" and "executing current cell and move to start of next" etc.

It would be nice if this plugin can provide something similar?

hkupty commented 2 years ago

Some repls support bracketed paste, which iron has implemented already. For this case, you can add the following to your repl definition and it should work:

matlab = {
    open = "%%",
    close = "%%",
    command = {
        "matlab",
        "-nosplash",
        "-nodesktop",
    },
}
hkupty commented 2 years ago

Or maybe I misunderstood what you said.

Since you can send motions to the repl, I would imagine this would be a feature better suited for a matlab specific plugin (to create a motion for a code block) then for iron. However, things might be a bit better once iron picks up support for treesitter.

I'm not really sure how to add this support to be fair, but it might be interesting to think about it even as a plugin on top of iron - that transforms literate code documents (documentation with code blocks) into executable code blocks using iron under the hood.

v-i-s-h commented 2 years ago

Using this function in init.lua

IronSendCell = function()
  local iron_core = require('iron.core')  
  local marks = require('iron.marks')

  local cell_pattern = "^\\s*##"  -- cell delimiter pattern
  local cell_start = vim.fn.search(cell_pattern, 'bcnW')
  local cell_end = vim.fn.search(cell_pattern, 'nW')

  local lines = vim.api.nvim_buf_get_lines(0, cell_start, cell_end-1, 0)
  -- ignore blank lines
  local b_lines = {}
  for i, line in ipairs(lines) do
    if line:gsub("^%s*(.-)%s*$", "%1") ~= '' then
      table.insert(b_lines, line)
    end
  end
  if #b_lines == 0 then return end

  if cell_start == 0 then
    cell_start = 1 -- if first cell, then start from first line
  end
  if cell_end == 0 then
    cell_end = vim.fn.line('$') -- set to last line
  end

  marks.set{ from_line=cell_start, from_col=0, to_line=cell_end, to_col=-1 }
  marks.winrestview()

  iron_core.send(nil, b_lines)
  vim.fn.cursor(cell_end+1, 0) -- move to next cell start
end

Finally, map this to Alt + Enter using

vim.keymap.set('', '<M-Enter>', IronSendCell)

This will send the cell delimited by a pair of ## to Iron REPL and move to next cell. Modify cell_pattern to suite to your need.