Skip to content
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

Add support for form indentation on slurp/barf #9

Merged
merged 5 commits into from
Sep 11, 2023

Conversation

julienvincent
Copy link
Owner

@julienvincent julienvincent commented Jul 30, 2023

This adds support for automatic indentation correction when slurping and barfing.

The goal of this implementation is to:

  1. Provide a visual aid to the user that allows them to confirm they are operating on the correct node, and to know when to stop when performing recursive slurp/barf operations.
  2. Be simple to maintain and understand while being as correct as possible
  3. Be replaceable with other implementations.
  4. Be as performant as possible. There should be no lag or visual jitter

The goal is not to be 100% correct. If a more correct implementation is needed then one can be provided through indent_fn. For example, an implementation using vim.lsp.buf.format could be built if the user doesn't mind sacrificing performance for correctness.

@armed
Copy link
Collaborator

armed commented Jul 31, 2023

Also added zprint support, it is a third party cli tool and it is much faster than LSP approach. To play around with it add this you your config somewhere:

local function zpr(input)
  -- assuming zprint binary name is "zpr" and it is available in PATH
  local result = vim.fn.system("echo '" .. input .. "' | zpr '{:style [:indent-only :respect-nl]}'")
  if result then
    return result:gsub("\r?\n$", "")
  end
  return input
end

local function zprint_indent(buf, start, end_)
  local api = vim.api
  local lines = api.nvim_buf_get_text(buf, start[1], 0, end_[1], end_[2], {})
  local text = table.concat(lines, "\n")
  local result = zpr(text)
  if result then
    local base_indent = string.rep(" ", start[2])
    local formatted_lines = {}
    for line in result:gmatch("[^\r\n]+") do
      table.insert(formatted_lines, base_indent .. line)
    end
    api.nvim_buf_set_text(buf, start[1], 0, end_[1], end_[2], formatted_lines)
  end
end

and then add an option to point to indent function indent_behaviour = zprint_indent

@armed
Copy link
Collaborator

armed commented Jul 31, 2023

Function zprint_indent is currently not part of a plugin, but we can include it as a general indent wrapper which passes input text and handles output text from functions such as zpr above.

@armed
Copy link
Collaborator

armed commented Aug 13, 2023

my last two commits are assuming that boundary symbol only 1 char length, but it is incorrect in case of #{ #( etc, need to handle that properly also, so still WIP

@armed
Copy link
Collaborator

armed commented Aug 14, 2023

reverted last 4 commits, experiments failed :)

Copy link
Collaborator

@armed armed left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

super close to perfection :)

except this is not indenting:

@(foo|)
@(bar)

@julienvincent
Copy link
Owner Author

Good catch. Fixed!

@julienvincent julienvincent merged commit e63ad68 into master Sep 11, 2023
2 checks passed
@julienvincent julienvincent deleted the auto-indentation branch September 11, 2023 13:28
@julienvincent julienvincent restored the auto-indentation branch October 13, 2024 12:14
@julienvincent julienvincent deleted the auto-indentation branch October 13, 2024 12:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants