runtime(karel): Add indent plugin for Karel

closes: #20357

Signed-off-by: Patrick Meiser-Knosowski <knosowski@graeffrobotics.de>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
Patrick Meiser-Knosowski
2026-05-29 18:19:39 +00:00
committed by Christian Brabandt
parent c83d2f888e
commit f31407f9fa
4 changed files with 544 additions and 0 deletions
+1
View File
@@ -405,6 +405,7 @@ runtime/indent/json.vim @elzr
runtime/indent/jsonc.vim @izhakjakov
runtime/indent/julia.vim @carlobaldassi
runtime/indent/just.vim @pbnj
runtime/indent/karel.vim @KnoP-01
runtime/indent/kdl.vim @imsnif @jiangyinzuo
runtime/indent/kotlin.vim @udalov
runtime/indent/krl.vim @KnoP-01
+121
View File
@@ -0,0 +1,121 @@
" Vim indent file
" Language: Fanuc Karel
" Maintainer: Patrick Meiser-Knosowski <knosowski@graeffrobotics.de>
" Version: 1.0.0
" Last Change: 28. May 2026
" Only load this indent file when no other was loaded.
if exists("b:did_indent")
finish
endif
let b:did_indent = 1
setlocal nolisp
setlocal nocindent
setlocal nosmartindent
setlocal autoindent
setlocal indentexpr=GetKarelIndent()
setlocal indentkeys=!^F,o,O,=~end,0=~else,0=~case,0=~until,0=~const,0=~type,0=~var,0=~begin
let b:undo_indent = "setlocal lisp< cindent< smartindent< autoindent< indentexpr< indentkeys<"
if get(g:,'karelSpaceIndent',1)
" Use spaces, not tabs, for indention, 2 is enough.
" More or even tabs would waste valuable space on the teach pendant.
setlocal softtabstop=2
setlocal shiftwidth=2
setlocal expandtab
setlocal shiftround
let b:undo_indent = b:undo_indent." softtabstop< shiftwidth< expandtab< shiftround<"
endif
" Only define the function once.
if exists("*GetKarelIndent")
finish
endif
let s:keepcpo = &cpo
set cpo&vim
function GetKarelIndent() abort
let currentLine = getline(v:lnum)
if currentLine =~? '\v^--' && !get(g:, 'karelCommentIndent', 0)
" If current line has a -- in column 1, keep zero indent.
" This may be useful if code is commented out at the first column.
return 0
endif
" Find a non-blank line above the current line.
let preNoneBlankLineNum = s:karelPreNoneBlank(v:lnum - 1)
if preNoneBlankLineNum == 0
" At the start of the file use zero indent.
return 0
endif
let preNoneBlankLine = getline(preNoneBlankLineNum)
let ind = indent(preNoneBlankLineNum)
" Define add 'shiftwidth' pattern
let addShiftwidthPattern = '\v^\s*('
let addShiftwidthPattern ..= 'if>|while>|for>|using>|condition>|.*<structure>'
let addShiftwidthPattern ..= '|else>'
let addShiftwidthPattern ..= '|case>'
let addShiftwidthPattern ..= '|repeat>'
let addShiftwidthPattern ..= '|const>'
let addShiftwidthPattern ..= '|type>'
let addShiftwidthPattern ..= '|var>'
let addShiftwidthPattern ..= '|begin>'
let addShiftwidthPattern ..= '|routine>'
if get(g:, 'karelIndentBetweenPrg', 1)
let addShiftwidthPattern ..= '|program>'
endif
let addShiftwidthPattern ..= ')'
" Define Subtract 'shiftwidth' pattern
let subtractShiftwidthPattern = '\v^\s*('
let subtractShiftwidthPattern ..= 'end(if|while|for|using|condition|structure)?>'
let subtractShiftwidthPattern ..= '|else>'
let subtractShiftwidthPattern ..= '|case>|endselect>'
let subtractShiftwidthPattern ..= '|until>'
let subtractShiftwidthPattern ..= '|const>'
let subtractShiftwidthPattern ..= '|type>'
let subtractShiftwidthPattern ..= '|var>'
let subtractShiftwidthPattern ..= '|begin>'
let subtractShiftwidthPattern ..= ')'
" Add shiftwidth
if preNoneBlankLine =~? addShiftwidthPattern
let ind += &sw
endif
" Subtract shiftwidth
if currentLine =~? subtractShiftwidthPattern
let ind = ind - &sw
endif
" First case after a select gets the indent of the select.
if currentLine =~? '\v^\s*case>'
\&& preNoneBlankLine =~? '\v^\s*select>'
let ind = ind + &sw
endif
return ind
endfunction
" This function works almost like prevnonblank() but handles &-headers,
" comments and continue instructions like blank lines
function s:karelPreNoneBlank(lnum) abort
let nPreNoneBlank = prevnonblank(a:lnum)
while nPreNoneBlank > 0 && getline(nPreNoneBlank) =~? '\v^\s*(\&\w\+|--)'
" Previous none blank line irrelevant. Look further aback.
let nPreNoneBlank = prevnonblank(nPreNoneBlank - 1)
endwhile
return nPreNoneBlank
endfunction
let &cpo = s:keepcpo
unlet s:keepcpo
" vim:sw=2 sts=2 et
+211
View File
@@ -0,0 +1,211 @@
-- vim: set ft=karel sw=2 :
-- START_INDENT
-- upper case
-- test karelIndentBetweenPrg not existing
-- test karelCommentIndent not existing
PROGRAM UcKarelPrg
%CMOSVARS
TYPE
Array4OfInt = ARRAY[4] OF integer
CONST
Success = 0
TYPE
sub_struct = STRUCTURE
subs_field_1: INTEGER
subs_field_2: BOOLEAN
ENDSTRUCTURE
MyStruct = STRUCTURE
subs_field_1: INTEGER
subs_field_2: sub_struct
ENDSTRUCTURE
VAR
i1 :integer
b1 :boolean
fhCh :file
ROUTINE prg1()
VAR
i :integer
BEGIN
--
END prg1
ROUTINE fcnt1( s :string ) :string
VAR
i :integer
BEGIN
RETURN ' '
END fcnt1
BEGIN
IF b1 THEN
--
ENDIF
IF b1 THEN
--
ELSE
--
ENDIF
WHILE b1 DO
--
ENDWHILE
FOR i1 = 1 TO 10 DO
--
ENDFOR
FOR i1 = 10 DOWNTO 1 DO
--
ENDFOR
USING sub_struct, MyStruct DO
--
ENDUSING
CONDITION[1]:
WHEN DIN[1] DO DOUT[1] = TRUE
ENDCONDITION
SELECT i1 OF
CASE (1):
--
CASE (2,3):
--
ELSE:
--
ENDSELECT
END UcKarelPrg
-- END_INDENT
-- START_INDENT
-- lower case
-- INDENT_EXE let g:karelIndentBetweenPrg = 0
-- INDENT_EXE let g:karelCommentIndent = 0
program LcKarelPrg
%CMOSVARS
type
Array4OfInt = ARRAY[4] OF integer
const
Success = 0
type
sub_struct = structure
subs_field_1: INTEGER
subs_field_2: BOOLEAN
endstructure
MyStruct = structure
subs_field_1: INTEGER
subs_field_2: sub_struct
endstructure
var
i1 :integer
b1 :boolean
fhCh :file
routine prg1()
var
i :integer
begin
--
end prg1
routine fcnt1( s :string ) :string
var
i :integer
begin
return ' '
end fcnt1
begin
if b1 then
--
endif
if b1 then
--
else
--
endif
while b1 do
--
endwhile
for i1 = 1 to 10 do
--
endfor
for i1 = 10 downto 1 do
--
endfor
using sub_struct, MyStruct do
--
endusing
condition[1]:
when DIN[1] do DOUT[1] = TRUE
endcondition
select i1 of
case (1):
--
case (2,3):
--
else:
--
endselect
end LcKarelPrg
-- END_INDENT
-- START_INDENT
-- mixed case
-- INDENT_EXE let g:karelIndentBetweenPrg = 1
-- INDENT_EXE let g:karelCommentIndent = 1
Program McKarelPrg
%CMOSVARS
Type
Array4OfInt = ARRAY[4] OF integer
Const
Success = 0
Type
sub_struct = Structure
subs_field_1: INTEGER
subs_field_2: BOOLEAN
EndStructure
MyStruct = Structure
subs_field_1: INTEGER
subs_field_2: sub_struct
EndStructure
Var
i1 :integer
b1 :boolean
fhCh :file
Routine prg1()
Var
i :integer
Begin
--
End prg1
Routine fcnt1( s :string ) :string
Var
i :integer
Begin
Return ' '
End fcnt1
Begin
If b1 Then
--
EndIf
If b1 Then
--
Else
--
EndIf
While b1 Do
--
EndWhile
For i1 = 1 To 10 Do
--
EndFor
For i1 = 10 DownTo 1 Do
--
EndFor
Using sub_struct, MyStruct Do
--
EndUsing
Condition[1]:
When DIN[1] Do DOUT[1] = TRUE
EndCondition
Select i1 Of
Case (1):
--
Case (2,3):
--
Else:
--
EndSelect
End McKarelPrg
-- END_INDENT
+211
View File
@@ -0,0 +1,211 @@
-- vim: set ft=karel sw=2 :
-- START_INDENT
-- upper case
-- test karelIndentBetweenPrg not existing
-- test karelCommentIndent not existing
PROGRAM UcKarelPrg
%CMOSVARS
TYPE
Array4OfInt = ARRAY[4] OF integer
CONST
Success = 0
TYPE
sub_struct = STRUCTURE
subs_field_1: INTEGER
subs_field_2: BOOLEAN
ENDSTRUCTURE
MyStruct = STRUCTURE
subs_field_1: INTEGER
subs_field_2: sub_struct
ENDSTRUCTURE
VAR
i1 :integer
b1 :boolean
fhCh :file
ROUTINE prg1()
VAR
i :integer
BEGIN
--
END prg1
ROUTINE fcnt1( s :string ) :string
VAR
i :integer
BEGIN
RETURN ' '
END fcnt1
BEGIN
IF b1 THEN
--
ENDIF
IF b1 THEN
--
ELSE
--
ENDIF
WHILE b1 DO
--
ENDWHILE
FOR i1 = 1 TO 10 DO
--
ENDFOR
FOR i1 = 10 DOWNTO 1 DO
--
ENDFOR
USING sub_struct, MyStruct DO
--
ENDUSING
CONDITION[1]:
WHEN DIN[1] DO DOUT[1] = TRUE
ENDCONDITION
SELECT i1 OF
CASE (1):
--
CASE (2,3):
--
ELSE:
--
ENDSELECT
END UcKarelPrg
-- END_INDENT
-- START_INDENT
-- lower case
-- INDENT_EXE let g:karelIndentBetweenPrg = 0
-- INDENT_EXE let g:karelCommentIndent = 0
program LcKarelPrg
%CMOSVARS
type
Array4OfInt = ARRAY[4] OF integer
const
Success = 0
type
sub_struct = structure
subs_field_1: INTEGER
subs_field_2: BOOLEAN
endstructure
MyStruct = structure
subs_field_1: INTEGER
subs_field_2: sub_struct
endstructure
var
i1 :integer
b1 :boolean
fhCh :file
routine prg1()
var
i :integer
begin
--
end prg1
routine fcnt1( s :string ) :string
var
i :integer
begin
return ' '
end fcnt1
begin
if b1 then
--
endif
if b1 then
--
else
--
endif
while b1 do
--
endwhile
for i1 = 1 to 10 do
--
endfor
for i1 = 10 downto 1 do
--
endfor
using sub_struct, MyStruct do
--
endusing
condition[1]:
when DIN[1] do DOUT[1] = TRUE
endcondition
select i1 of
case (1):
--
case (2,3):
--
else:
--
endselect
end LcKarelPrg
-- END_INDENT
-- START_INDENT
-- mixed case
-- INDENT_EXE let g:karelIndentBetweenPrg = 1
-- INDENT_EXE let g:karelCommentIndent = 1
Program McKarelPrg
%CMOSVARS
Type
Array4OfInt = ARRAY[4] OF integer
Const
Success = 0
Type
sub_struct = Structure
subs_field_1: INTEGER
subs_field_2: BOOLEAN
EndStructure
MyStruct = Structure
subs_field_1: INTEGER
subs_field_2: sub_struct
EndStructure
Var
i1 :integer
b1 :boolean
fhCh :file
Routine prg1()
Var
i :integer
Begin
--
End prg1
Routine fcnt1( s :string ) :string
Var
i :integer
Begin
Return ' '
End fcnt1
Begin
If b1 Then
--
EndIf
If b1 Then
--
Else
--
EndIf
While b1 Do
--
EndWhile
For i1 = 1 To 10 Do
--
EndFor
For i1 = 10 DownTo 1 Do
--
EndFor
Using sub_struct, MyStruct Do
--
EndUsing
Condition[1]:
When DIN[1] Do DOUT[1] = TRUE
EndCondition
Select i1 Of
Case (1):
--
Case (2,3):
--
Else:
--
EndSelect
End McKarelPrg
-- END_INDENT