feat: improve formatter and attribute block handling
- Format multi-line assignments with proper alignment - Format FB calls in multiline style with parameter alignment - Auto-expand collapsed attribute blocks before save - Rename command from LspSCLFormat to SCLFormat - Condense AGENTS.md and add testing section with reference project
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# AGENTS.md - SCL Language Server
|
||||
|
||||
A unified Neovim/LazyVim plugin for Siemens SCL language support providing LSP, linting, formatting, syntax highlighting, and auto-completion.
|
||||
A Neovim/LazyVim plugin for Siemens SCL language support providing LSP, linting, formatting, syntax highlighting, and auto-completion.
|
||||
|
||||
## Build/Lint/Test Commands
|
||||
|
||||
@@ -12,7 +12,7 @@ lua src/main.lua --test # Direct test execution
|
||||
|
||||
# Tree-sitter Parser
|
||||
tree-sitter generate # Generate parser from grammar.js
|
||||
tree-sitter test # Run parser tests
|
||||
tree-sitter test # Run all parser tests
|
||||
tree-sitter parse <file.scl> # Parse single SCL file
|
||||
|
||||
# Lua Linting
|
||||
@@ -31,11 +31,10 @@ scl_lsp/
|
||||
│ ├── formatter.lua # Document formatter
|
||||
│ ├── treesitter.lua # Tree-sitter integration
|
||||
│ ├── plc_json.lua # External UDT/DB loading
|
||||
│ ├── builtin_instructions.lua # TIA Portal built-in types/FBs/functions
|
||||
│ ├── builtin_instructions.lua # TIA Portal built-in types
|
||||
│ └── json.lua # JSON encoder/decoder
|
||||
├── lua/scl/ # Neovim plugin (uses require)
|
||||
│ ├── init.lua # Main plugin setup
|
||||
│ ├── blink_cmp_source.lua
|
||||
│ ├── udt_parser.lua # UDT parser
|
||||
│ ├── db_parser.lua # Global DB parser
|
||||
│ ├── fb_parser.lua # Function Block parser
|
||||
@@ -43,34 +42,26 @@ scl_lsp/
|
||||
│ ├── workspace_types.lua # Workspace scanning
|
||||
│ ├── multiline_params.lua
|
||||
│ ├── auto_prefix.lua
|
||||
│ └── attr_toggle.lua # Interactive attribute block toggle
|
||||
│ └── attr_toggle.lua
|
||||
├── queries/ # Tree-sitter queries
|
||||
│ ├── highlights.scm
|
||||
│ ├── indents.scm
|
||||
│ └── folds.scm
|
||||
└── grammar.js # Tree-sitter grammar
|
||||
```
|
||||
|
||||
## Filetype Detection
|
||||
|
||||
The LSP requires the `scl` filetype to be set. Add to your Neovim config (e.g., `ftdetect/scl.vim`):
|
||||
|
||||
Required in Neovim config (ftdetect/scl.vim):
|
||||
```vim
|
||||
au BufRead,BufNewFile *.scl set filetype=scl
|
||||
au BufRead,BufNewFile *.udt set filetype=scl
|
||||
au BufRead,BufNewFile *.db set filetype=scl
|
||||
```
|
||||
|
||||
This enables LSP features (completion, goto definition, hover, etc.) for all SCL-related file types.
|
||||
|
||||
## Code Style Guidelines
|
||||
|
||||
### Module Pattern
|
||||
```lua
|
||||
-- File header comment
|
||||
local M = {}
|
||||
|
||||
-- Private cache
|
||||
local cache = {}
|
||||
|
||||
function M.public_function()
|
||||
@@ -89,8 +80,8 @@ return M
|
||||
- Booleans: prefix with `is_`, `has_` (e.g., `is_udt`, `has_members`)
|
||||
|
||||
### Imports
|
||||
- `lua/scl/` modules: use `require("scl.module_name")`
|
||||
- `src/` modules: use `dofile(script_path .. "/module.lua")`
|
||||
- `lua/scl/` modules: `require("scl.module_name")`
|
||||
- `src/` modules: `dofile(script_path .. "/module.lua")`
|
||||
- External dependencies: wrap in `pcall()` for safety
|
||||
|
||||
### Code Formatting
|
||||
@@ -99,6 +90,9 @@ return M
|
||||
- Max line length: 120 characters
|
||||
- No trailing whitespace
|
||||
|
||||
### Comments
|
||||
**DO NOT ADD COMMENTS** in code unless explicitly requested by the user.
|
||||
|
||||
### Parser Module API
|
||||
All parser modules must implement:
|
||||
- `parse_*_file(filepath)` - Parse and cache
|
||||
@@ -121,291 +115,54 @@ function M.clear_cache()
|
||||
end
|
||||
```
|
||||
|
||||
## Lua Reserved Keywords
|
||||
|
||||
Cannot use reserved keywords as table keys directly:
|
||||
```lua
|
||||
-- WRONG: syntax error
|
||||
local range = { start = pos1, end = pos2 }
|
||||
|
||||
-- CORRECT: bracket notation
|
||||
local range = { start = pos1, ["end"] = pos2 }
|
||||
```
|
||||
|
||||
Critical for LSP range objects with `end` field.
|
||||
|
||||
## Error Handling
|
||||
|
||||
### Return Pattern
|
||||
### Error Handling
|
||||
```lua
|
||||
function M.parse_file(filepath)
|
||||
local file = io.open(filepath, "r")
|
||||
if not file then
|
||||
return nil, "Cannot open file: " .. filepath
|
||||
end
|
||||
-- ... parse logic
|
||||
return result
|
||||
end
|
||||
```
|
||||
|
||||
### External Dependencies
|
||||
```lua
|
||||
-- External dependencies
|
||||
local ok, module = pcall(require, "some_module")
|
||||
if ok and module then
|
||||
module.do_something()
|
||||
end
|
||||
```
|
||||
|
||||
## Diagnostics
|
||||
|
||||
The LSP validates data types and provides warnings for unknown types. It recognizes:
|
||||
- **Elementary data types** - BOOL, BYTE, WORD, DWORD, LWORD, CHAR, WCHAR, STRING, WSTRING, INT, DINT, LINT, USINT, SINT, UINT, UDINT, ULINT, REAL, LREAL, TIME, DATE, TOD, TIME_OF_DAY, DATE_AND_TIME, DT, S5TIME, LTIME, DTL
|
||||
- **Timer/counter types** - IEC_TIMER, TON_TIME, TOF_TIME, TONR_TIME, TP_TIME, CTU, CTD, CTUD
|
||||
- **TIA Portal built-in instructions** - Functions and function blocks
|
||||
- **Workspace types** - UDTs from `.udt` files and data blocks from `.db` files
|
||||
|
||||
## Completion Triggers
|
||||
- `#` - Local variables (after BEGIN)
|
||||
- `.` - Member access (UDT/DB)
|
||||
- `"` - Global DB names
|
||||
- `(` - FB/Function parameters
|
||||
- ` ` (space) - General completion
|
||||
- `:` - Type declaration (in VAR section)
|
||||
|
||||
### Completion Types
|
||||
The LSP provides auto-completion for:
|
||||
- **Local variables** - Variables declared in VAR sections
|
||||
- **UDT types** - User-defined types from `.udt` files
|
||||
- **Global DBs** - Data blocks from `.db` files
|
||||
- **Elementary types** - BOOL, INT, DINT, REAL, TIME, etc.
|
||||
- **TIA Portal built-in FBs** - TON, TOF, TP, CTU, CTD, CTUD, R_TRIG, etc.
|
||||
- **TIA Portal built-in functions** - ADD, SUB, MUL, DIV, SIN, COS, SQRT, etc.
|
||||
|
||||
## Formatter Options
|
||||
|
||||
The formatter supports collapsing verbose attribute blocks:
|
||||
## Lua Reserved Keywords
|
||||
|
||||
Cannot use reserved keywords as table keys directly:
|
||||
```lua
|
||||
-- Before formatting:
|
||||
statCntrPartsIn{EXTERNALACCESSIBLE := 'false'; EXTERNALVISIBLE := 'false'} : Int;
|
||||
-- WRONG
|
||||
local range = { start = pos1, end = pos2 }
|
||||
|
||||
-- After formatting:
|
||||
statCntrPartsIn{...} : Int;
|
||||
-- CORRECT
|
||||
local range = { start = pos1, ["end"] = pos2 }
|
||||
```
|
||||
|
||||
### Formatter Configuration
|
||||
```lua
|
||||
local options = {
|
||||
insertSpaces = false,
|
||||
tabSize = 1,
|
||||
collapseAttributes = false, -- Disabled by default (see note below)
|
||||
collapsePatterns = { -- Override default patterns
|
||||
"^%s*{%s*EXTERNAL",
|
||||
"^%s*{ S7_",
|
||||
},
|
||||
extendCollapsePatterns = { -- Add custom patterns
|
||||
"^%s*{%s*CUSTOM",
|
||||
},
|
||||
}
|
||||
```
|
||||
Critical for LSP range objects with `end` field.
|
||||
|
||||
**Note:** `collapseAttributes` is disabled by default to preserve compatibility with the interactive toggle feature (`:SCLToggleAttrBlock`). When the formatter automatically collapses blocks, the original content is lost. To use both formatting and toggle:
|
||||
1. Format with `:LspSCLFormat` (preserves original content)
|
||||
2. Manually collapse with `:SCLCollapseAllAttrBlocks` (stores original content)
|
||||
3. Now toggle/expand works correctly
|
||||
## Type System
|
||||
|
||||
### Default Collapse Patterns
|
||||
The `:SCLCollapseAllAttrBlocks` command uses case-insensitive patterns:
|
||||
- `EXTERNAL` - Variable attributes: `{EXTERNALACCESSIBLE := 'false'; EXTERNALVISIBLE := 'false'}`
|
||||
- `S7_` - Block attributes: `{S7_Optimized_Access := 'TRUE'}`
|
||||
- `NonRetain` - NonRetain attribute: `{NonRetain}`
|
||||
- `Retain` - Retain attribute: `{Retain}`
|
||||
- `%w+ :=` - Generic attributes with assignments: `{key := 'value'}`
|
||||
- `%w+` - Single word attributes: `{SomeAttribute}`
|
||||
|
||||
Works in `.scl`, `.udt`, and `.db` files.
|
||||
|
||||
### Per-Variable Collapse Rules
|
||||
Control collapsing per variable using rules (evaluated before global patterns):
|
||||
|
||||
```lua
|
||||
local options = {
|
||||
collapseVariableRules = {
|
||||
-- Collapse attributes for variables starting with "stat"
|
||||
{
|
||||
variablePattern = "^stat",
|
||||
collapse = true,
|
||||
},
|
||||
-- Never collapse for "temp" prefix variables
|
||||
{
|
||||
variablePattern = "^temp",
|
||||
collapse = false,
|
||||
},
|
||||
-- Collapse only if both variable AND attribute match
|
||||
{
|
||||
variablePattern = "^config",
|
||||
attributePattern = "EXTERNAL",
|
||||
collapse = true,
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
**Rule properties:**
|
||||
- `variablePattern` - Lua pattern to match variable name (optional)
|
||||
- `attributePattern` - Lua pattern to match attribute content (optional)
|
||||
- `collapse` - `true` to collapse to `{...}`, `false` to keep expanded
|
||||
|
||||
Rules are checked in order; first match wins.
|
||||
|
||||
## Commands
|
||||
|
||||
| Command | Description |
|
||||
|---------|-------------|
|
||||
| `:SCLShowVariables` | Show local variables |
|
||||
| `:SCLShowWorkspaceTypes` | Show workspace types count |
|
||||
| `:SCLRescanWorkspaceTypes` | Rescan workspace |
|
||||
| `:SCLPrefixWord` | Prefix word with `#` |
|
||||
| `:SCLMultilineParams` | Fill FB parameters |
|
||||
| `:LspSCLFormat` | Format SCL file |
|
||||
| `:SCLToggleAttrBlock` | Toggle attribute block under cursor |
|
||||
| `:SCLExpandAllAttrBlocks` | Expand all `{...}` blocks in buffer |
|
||||
| `:SCLCollapseAllAttrBlocks` | Collapse all matching attribute blocks |
|
||||
|
||||
## LSP Features
|
||||
|
||||
### Goto Declaration (`gD`)
|
||||
The LSP supports goto declaration functionality for:
|
||||
- **Functions** - Jump to function definition in `.scl` files
|
||||
- **Function Blocks (FB)** - Jump to FB definition in `.scl` files
|
||||
- **Data Blocks (DB)** - Jump to DB definition in `.scl` and `.db` files
|
||||
- **User-Defined Types (UDT)** - Jump to type definition in `.scl` and `.udt` files
|
||||
|
||||
Usage: Place cursor on a variable or type name and press `gD` (or use LSP client command).
|
||||
|
||||
## Auto-Editing Features
|
||||
|
||||
### Auto-Uppercase Keywords
|
||||
When typing SCL keywords followed by a space, they are automatically converted to uppercase:
|
||||
- `if ` → `IF `
|
||||
- `then ` → `THEN `
|
||||
- `end_if` → `END_IF`
|
||||
- etc.
|
||||
|
||||
Works in `.scl`, `.udt`, and `.db` files.
|
||||
|
||||
### Auto-Semicolon for Control Structures
|
||||
When pressing Enter after an `END_*` control structure keyword, a semicolon is automatically added:
|
||||
- `END_IF` → `END_IF;`
|
||||
- `END_FOR` → `END_FOR;`
|
||||
- `END_WHILE` → `END_WHILE;`
|
||||
- `END_REPEAT` → `END_REPEAT;`
|
||||
- `END_CASE` → `END_CASE;`
|
||||
|
||||
Block definitions (END_VAR, END_FUNCTION, etc.) are NOT affected.
|
||||
|
||||
### Auto-Prefix Local Variables
|
||||
Local variables are automatically prefixed with `#` when typing space or semicolon after BEGIN:
|
||||
- `myVar := ` → `#myVar := `
|
||||
- `counter.in` → `#counter.in` (on dot)
|
||||
|
||||
Can be toggled with `:lua require("scl.auto_prefix").toggle()`.
|
||||
|
||||
## Keybindings (SCL/UDT files)
|
||||
|
||||
### Attribute Block Toggle
|
||||
Interactive expand/collapse of individual `{...}` blocks (uses `<Leader>x` prefix):
|
||||
|
||||
| Key | Mode | Description |
|
||||
|-----|------|-------------|
|
||||
| `<Leader>xa` | Normal/Insert | Toggle block under cursor |
|
||||
| `<Leader>xae` | Normal | Expand all collapsed blocks |
|
||||
| `<Leader>xac` | Normal | Collapse all attribute blocks |
|
||||
|
||||
**How it works:**
|
||||
1. Place cursor inside any `{...}` block
|
||||
2. Press `<Leader>xa` to toggle between collapsed `{...}` and expanded content
|
||||
3. Original content is stored per-buffer and persists until buffer is closed
|
||||
4. Works on both formatter-collapsed blocks and manually collapsed ones
|
||||
|
||||
### Other Keybindings
|
||||
|
||||
| Key | Mode | Description |
|
||||
|-----|------|-------------|
|
||||
| `<Space>mp` | Insert | Fill multiline FB parameters |
|
||||
| `<Tab>` | Insert | Jump to next parameter or regular Tab |
|
||||
|
||||
Note: `<Leader>` is typically `\` (backslash) or `<Space>` depending on your configuration.
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
**If commands or keybindings don't work:**
|
||||
|
||||
1. Check if setup() was called:
|
||||
```lua
|
||||
:lua print(vim.inspect(require("scl_lsp")))
|
||||
```
|
||||
|
||||
2. Verify commands exist:
|
||||
```vim
|
||||
:command SCLToggleAttrBlock
|
||||
```
|
||||
Should show the command definition.
|
||||
|
||||
3. Check for errors during setup:
|
||||
```lua
|
||||
:lua require("scl_lsp").setup({})
|
||||
```
|
||||
|
||||
4. Verify leader key:
|
||||
```vim
|
||||
:echo mapleader
|
||||
```
|
||||
If empty, your leader is `\` (backslash).
|
||||
|
||||
5. Manual test keybinding:
|
||||
```vim
|
||||
:nmap <Leader>xa
|
||||
```
|
||||
Should show the mapping.
|
||||
|
||||
### Attribute Toggle After Formatting
|
||||
|
||||
**Note:** After using `:LspSCLFormat`, all collapsed attribute blocks will be expanded and the toggle state is reset. This is because formatting changes line numbers and positions. You can collapse blocks again after formatting.
|
||||
The LSP validates data types and provides warnings for unknown types:
|
||||
- **Elementary**: BOOL, BYTE, WORD, DWORD, INT, DINT, REAL, TIME, STRING, etc.
|
||||
- **Timer/counter**: IEC_TIMER, TON_TIME, TOF_TIME, CTU, CTD, CTUD
|
||||
- **Built-in FBs**: TON, TOF, TP, R_TRIG, F_TRIG, etc.
|
||||
- **Built-in functions**: ADD, SUB, MUL, DIV, SIN, COS, SQRT, etc.
|
||||
- **Workspace types**: UDTs from `.udt` files, DBs from `.db` files
|
||||
|
||||
## Testing
|
||||
|
||||
Manual testing using: `~/dev/siemens/projects/scl_lang_support_lazyvim_ref_project`
|
||||
|
||||
Workflow:
|
||||
1. Open `.scl` file in Neovim
|
||||
2. Test LSP features (hover, completion, go-to-definition)
|
||||
3. Verify diagnostics
|
||||
4. Test formatting
|
||||
5. Check workspace scanning
|
||||
|
||||
## LSP Implementation Notes
|
||||
|
||||
### Method Name Conversion
|
||||
```lua
|
||||
local method_name = message.method:gsub("/", "_")
|
||||
local handler = handlers[method_name]
|
||||
Use the reference project for testing:
|
||||
```
|
||||
~/dev/siemens/projects/scl_lang_support_lazyvim_ref_project/
|
||||
```
|
||||
|
||||
### Request vs Notification
|
||||
```lua
|
||||
if message.id then
|
||||
-- Request: send response
|
||||
return { id = message.id, result = result }
|
||||
end
|
||||
-- Notification: no response needed
|
||||
```
|
||||
|
||||
### Script Path Pattern
|
||||
```lua
|
||||
local script_path = debug.getinfo(1, "S").source:gsub("^@", ""):match("(.*/)") or ""
|
||||
if script_path == "" then
|
||||
script_path = "."
|
||||
end
|
||||
package.path = package.path .. ";" .. script_path .. "/?.lua"
|
||||
```
|
||||
Contains `.scl`, `.db`, `.udt`, and `.xml` files for comprehensive testing of:
|
||||
- LSP features (hover, completion, go-to-definition)
|
||||
- Formatter (`:SCLFormat`)
|
||||
- Attribute block toggle
|
||||
- Workspace type scanning
|
||||
|
||||
@@ -27,7 +27,9 @@ A comprehensive Neovim/LazyVim plugin providing **Language Server Protocol (LSP)
|
||||
### Formatter
|
||||
| Feature | Description |
|
||||
|---------|-------------|
|
||||
| **Document Formatting** | Format entire SCL files |
|
||||
| **Document Formatting** | Format entire SCL files with `:SCLFormat` |
|
||||
| **Multi-line Assignments** | Preserves and formats multi-line expressions with proper alignment |
|
||||
| **FB Call Formatting** | Formats function block calls in multiline style |
|
||||
| **Indentation** | Proper block indentation |
|
||||
| **Keyword Casing** | Maintains SCL keyword casing |
|
||||
|
||||
@@ -119,8 +121,7 @@ require("scl_lsp").setup({
|
||||
| `:SCLRescanWorkspaceTypes` | Rescan workspace for types and DBs |
|
||||
| `:SCLPrefixWord` | Manually prefix current word with `#` |
|
||||
| `:SCLMultilineParams` | Fill multiline parameters for FB/Function call |
|
||||
| `:LspSCLFormat` | Format current SCL file |
|
||||
| `:SCLGeneratePlcJson` | Generate plc.data.json from data_types/ |
|
||||
| `:SCLFormat` | Format current SCL file |
|
||||
| `:SCLToggleAttrBlock` | Toggle attribute block under cursor |
|
||||
| `:SCLExpandAllAttrBlocks` | Expand all `{...}` blocks in buffer |
|
||||
| `:SCLCollapseAllAttrBlocks` | Collapse all matching attribute blocks |
|
||||
@@ -159,7 +160,7 @@ statCounter{...} : Int;
|
||||
- Use `<Leader>xae` to expand all blocks in buffer
|
||||
- Use `<Leader>xac` to collapse all blocks
|
||||
|
||||
**Note:** The formatter has automatic collapsing disabled by default to preserve compatibility with the toggle feature. Format with `:LspSCLFormat` first, then use `:SCLCollapseAllAttrBlocks` to collapse while preserving the ability to expand later.
|
||||
**Note:** Collapsed blocks are automatically expanded before saving to preserve full content on disk. Use `:SCLFormat` to format, then `:SCLCollapseAllAttrBlocks` to collapse while preserving the ability to expand later.
|
||||
|
||||
## External UDT Support
|
||||
|
||||
|
||||
+27
-5
@@ -80,23 +80,24 @@ function M.toggle_attr_block()
|
||||
end
|
||||
|
||||
-- Expand all collapsed blocks in current buffer
|
||||
function M.expand_all_attr_blocks()
|
||||
function M.expand_all_attr_blocks(opts)
|
||||
opts = opts or {}
|
||||
local bufnr = vim.api.nvim_get_current_buf()
|
||||
local lines = vim.api.nvim_buf_get_lines(bufnr, 0, -1, false)
|
||||
local count = 0
|
||||
|
||||
if not buffer_attr_state[bufnr] then
|
||||
vim.notify("No collapsed blocks to expand", vim.log.levels.INFO)
|
||||
if not opts.silent then
|
||||
vim.notify("No collapsed blocks to expand", vim.log.levels.INFO)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
for state_key, state in pairs(buffer_attr_state[bufnr]) do
|
||||
if state.is_collapsed then
|
||||
-- state.line_num is 1-indexed, but nvim_buf_get_lines returns 0-indexed array
|
||||
local line = lines[state.line_num]
|
||||
|
||||
if line then
|
||||
-- Find the collapsed {...} and replace with expanded content
|
||||
local new_line = line:sub(1, state.start_col) .. state.expanded .. line:sub(state.start_col + 4)
|
||||
lines[state.line_num] = new_line
|
||||
state.is_collapsed = false
|
||||
@@ -106,7 +107,9 @@ function M.expand_all_attr_blocks()
|
||||
end
|
||||
|
||||
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, lines)
|
||||
vim.notify("Expanded " .. count .. " attribute block(s)", vim.log.levels.INFO)
|
||||
if not opts.silent and count > 0 then
|
||||
vim.notify("Expanded " .. count .. " attribute block(s)", vim.log.levels.INFO)
|
||||
end
|
||||
end
|
||||
|
||||
-- Helper to make a pattern case-insensitive
|
||||
@@ -193,6 +196,25 @@ end
|
||||
function M.setup()
|
||||
local augroup = vim.api.nvim_create_augroup("SCLAttrToggle", { clear = true })
|
||||
|
||||
vim.api.nvim_create_autocmd("BufWritePre", {
|
||||
group = augroup,
|
||||
pattern = { "*.scl", "*.udt", "*.db" },
|
||||
callback = function(args)
|
||||
if buffer_attr_state[args.buf] then
|
||||
local has_collapsed = false
|
||||
for _, state in pairs(buffer_attr_state[args.buf]) do
|
||||
if state.is_collapsed then
|
||||
has_collapsed = true
|
||||
break
|
||||
end
|
||||
end
|
||||
if has_collapsed then
|
||||
M.expand_all_attr_blocks({ silent = true })
|
||||
end
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
vim.api.nvim_create_autocmd("BufUnload", {
|
||||
group = augroup,
|
||||
pattern = { "*.scl", "*.udt", "*.db" },
|
||||
|
||||
@@ -34,9 +34,8 @@ function M.setup(opts)
|
||||
end
|
||||
|
||||
if opts.lsp and opts.lsp.formatting then
|
||||
vim.api.nvim_buf_create_user_command(b, "LspSCLFormat", function()
|
||||
vim.api.nvim_buf_create_user_command(b, "SCLFormat", function()
|
||||
vim.lsp.buf.format({ name = "scl_lsp" })
|
||||
-- Clear attr_toggle state since line positions may have changed
|
||||
local ok, at = pcall(require, "scl.attr_toggle")
|
||||
if ok then
|
||||
at.clear_buffer_state(vim.api.nvim_get_current_buf())
|
||||
@@ -56,9 +55,8 @@ function M.setup(opts)
|
||||
})
|
||||
|
||||
-- Create global format command (works on current buffer)
|
||||
vim.api.nvim_create_user_command("LspSCLFormat", function()
|
||||
vim.api.nvim_create_user_command("SCLFormat", function()
|
||||
vim.lsp.buf.format({ name = "scl_lsp" })
|
||||
-- Clear attr_toggle state since line positions may have changed
|
||||
local ok, at = pcall(require, "scl.attr_toggle")
|
||||
if ok then
|
||||
at.clear_buffer_state(vim.api.nvim_get_current_buf())
|
||||
|
||||
Reference in New Issue
Block a user