mirror of
https://github.com/Myzel394/config-lsp.git
synced 2025-06-19 07:25:27 +02:00
feat(sshd_config): Improvements; Add basic root completions
This commit is contained in:
parent
02b4a53480
commit
6383fbba17
@ -5,7 +5,7 @@ lineStatement
|
||||
;
|
||||
|
||||
entry
|
||||
: WHITESPACE? key? WHITESPACE value? WHITESPACE? leadingComment?
|
||||
: WHITESPACE? key? WHITESPACE? value? WHITESPACE? leadingComment?
|
||||
;
|
||||
|
||||
key
|
||||
|
@ -78,11 +78,10 @@ func (s *sshParserListener) EnterValue(ctx *parser.ValueContext) {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *sshParserListener) ExitValue(ctx *parser.ValueContext) {
|
||||
func (s *sshParserListener) ExitEntry(ctx *parser.EntryContext) {
|
||||
location := common.CharacterRangeFromCtx(ctx.BaseParserRuleContext)
|
||||
location.ChangeBothLines(s.sshContext.line)
|
||||
|
||||
|
||||
if s.sshContext.isKeyAMatchBlock {
|
||||
// Add new match block
|
||||
matchBlock := &SSHMatchBlock{
|
||||
|
@ -21,7 +21,7 @@ func NewSSHConfig() *SSHConfig {
|
||||
|
||||
func (c *SSHConfig) Clear() {
|
||||
c.Options = treemap.NewWith(gods.UInt32Comparator)
|
||||
c.CommentLines = make(map[uint32]struct{})
|
||||
c.CommentLines = map[uint32]struct{}{}
|
||||
}
|
||||
|
||||
var commentPattern = regexp.MustCompile(`^\s*#.*$`)
|
||||
|
@ -21,4 +21,4 @@ leadingComment
|
||||
|
||||
|
||||
atn:
|
||||
[4, 1, 4, 59, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 1, 0, 1, 0, 3, 0, 13, 8, 0, 1, 0, 1, 0, 3, 0, 17, 8, 0, 3, 0, 19, 8, 0, 1, 0, 1, 0, 1, 1, 3, 1, 24, 8, 1, 1, 1, 3, 1, 27, 8, 1, 1, 1, 1, 1, 3, 1, 31, 8, 1, 1, 1, 3, 1, 34, 8, 1, 1, 1, 3, 1, 37, 8, 1, 1, 2, 1, 2, 1, 3, 1, 3, 3, 3, 43, 8, 3, 1, 3, 1, 3, 1, 4, 1, 4, 3, 4, 49, 8, 4, 1, 4, 1, 4, 3, 4, 53, 8, 4, 4, 4, 55, 8, 4, 11, 4, 12, 4, 56, 1, 4, 0, 0, 5, 0, 2, 4, 6, 8, 0, 0, 66, 0, 18, 1, 0, 0, 0, 2, 23, 1, 0, 0, 0, 4, 38, 1, 0, 0, 0, 6, 42, 1, 0, 0, 0, 8, 46, 1, 0, 0, 0, 10, 19, 3, 2, 1, 0, 11, 13, 5, 2, 0, 0, 12, 11, 1, 0, 0, 0, 12, 13, 1, 0, 0, 0, 13, 14, 1, 0, 0, 0, 14, 19, 3, 8, 4, 0, 15, 17, 5, 2, 0, 0, 16, 15, 1, 0, 0, 0, 16, 17, 1, 0, 0, 0, 17, 19, 1, 0, 0, 0, 18, 10, 1, 0, 0, 0, 18, 12, 1, 0, 0, 0, 18, 16, 1, 0, 0, 0, 19, 20, 1, 0, 0, 0, 20, 21, 5, 0, 0, 1, 21, 1, 1, 0, 0, 0, 22, 24, 5, 2, 0, 0, 23, 22, 1, 0, 0, 0, 23, 24, 1, 0, 0, 0, 24, 26, 1, 0, 0, 0, 25, 27, 3, 4, 2, 0, 26, 25, 1, 0, 0, 0, 26, 27, 1, 0, 0, 0, 27, 28, 1, 0, 0, 0, 28, 30, 5, 2, 0, 0, 29, 31, 3, 6, 3, 0, 30, 29, 1, 0, 0, 0, 30, 31, 1, 0, 0, 0, 31, 33, 1, 0, 0, 0, 32, 34, 5, 2, 0, 0, 33, 32, 1, 0, 0, 0, 33, 34, 1, 0, 0, 0, 34, 36, 1, 0, 0, 0, 35, 37, 3, 8, 4, 0, 36, 35, 1, 0, 0, 0, 36, 37, 1, 0, 0, 0, 37, 3, 1, 0, 0, 0, 38, 39, 5, 3, 0, 0, 39, 5, 1, 0, 0, 0, 40, 41, 5, 3, 0, 0, 41, 43, 5, 2, 0, 0, 42, 40, 1, 0, 0, 0, 42, 43, 1, 0, 0, 0, 43, 44, 1, 0, 0, 0, 44, 45, 5, 3, 0, 0, 45, 7, 1, 0, 0, 0, 46, 48, 5, 1, 0, 0, 47, 49, 5, 2, 0, 0, 48, 47, 1, 0, 0, 0, 48, 49, 1, 0, 0, 0, 49, 54, 1, 0, 0, 0, 50, 52, 5, 3, 0, 0, 51, 53, 5, 2, 0, 0, 52, 51, 1, 0, 0, 0, 52, 53, 1, 0, 0, 0, 53, 55, 1, 0, 0, 0, 54, 50, 1, 0, 0, 0, 55, 56, 1, 0, 0, 0, 56, 54, 1, 0, 0, 0, 56, 57, 1, 0, 0, 0, 57, 9, 1, 0, 0, 0, 12, 12, 16, 18, 23, 26, 30, 33, 36, 42, 48, 52, 56]
|
||||
[4, 1, 4, 61, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 1, 0, 1, 0, 3, 0, 13, 8, 0, 1, 0, 1, 0, 3, 0, 17, 8, 0, 3, 0, 19, 8, 0, 1, 0, 1, 0, 1, 1, 3, 1, 24, 8, 1, 1, 1, 3, 1, 27, 8, 1, 1, 1, 3, 1, 30, 8, 1, 1, 1, 3, 1, 33, 8, 1, 1, 1, 3, 1, 36, 8, 1, 1, 1, 3, 1, 39, 8, 1, 1, 2, 1, 2, 1, 3, 1, 3, 3, 3, 45, 8, 3, 1, 3, 1, 3, 1, 4, 1, 4, 3, 4, 51, 8, 4, 1, 4, 1, 4, 3, 4, 55, 8, 4, 4, 4, 57, 8, 4, 11, 4, 12, 4, 58, 1, 4, 0, 0, 5, 0, 2, 4, 6, 8, 0, 0, 69, 0, 18, 1, 0, 0, 0, 2, 23, 1, 0, 0, 0, 4, 40, 1, 0, 0, 0, 6, 44, 1, 0, 0, 0, 8, 48, 1, 0, 0, 0, 10, 19, 3, 2, 1, 0, 11, 13, 5, 2, 0, 0, 12, 11, 1, 0, 0, 0, 12, 13, 1, 0, 0, 0, 13, 14, 1, 0, 0, 0, 14, 19, 3, 8, 4, 0, 15, 17, 5, 2, 0, 0, 16, 15, 1, 0, 0, 0, 16, 17, 1, 0, 0, 0, 17, 19, 1, 0, 0, 0, 18, 10, 1, 0, 0, 0, 18, 12, 1, 0, 0, 0, 18, 16, 1, 0, 0, 0, 19, 20, 1, 0, 0, 0, 20, 21, 5, 0, 0, 1, 21, 1, 1, 0, 0, 0, 22, 24, 5, 2, 0, 0, 23, 22, 1, 0, 0, 0, 23, 24, 1, 0, 0, 0, 24, 26, 1, 0, 0, 0, 25, 27, 3, 4, 2, 0, 26, 25, 1, 0, 0, 0, 26, 27, 1, 0, 0, 0, 27, 29, 1, 0, 0, 0, 28, 30, 5, 2, 0, 0, 29, 28, 1, 0, 0, 0, 29, 30, 1, 0, 0, 0, 30, 32, 1, 0, 0, 0, 31, 33, 3, 6, 3, 0, 32, 31, 1, 0, 0, 0, 32, 33, 1, 0, 0, 0, 33, 35, 1, 0, 0, 0, 34, 36, 5, 2, 0, 0, 35, 34, 1, 0, 0, 0, 35, 36, 1, 0, 0, 0, 36, 38, 1, 0, 0, 0, 37, 39, 3, 8, 4, 0, 38, 37, 1, 0, 0, 0, 38, 39, 1, 0, 0, 0, 39, 3, 1, 0, 0, 0, 40, 41, 5, 3, 0, 0, 41, 5, 1, 0, 0, 0, 42, 43, 5, 3, 0, 0, 43, 45, 5, 2, 0, 0, 44, 42, 1, 0, 0, 0, 44, 45, 1, 0, 0, 0, 45, 46, 1, 0, 0, 0, 46, 47, 5, 3, 0, 0, 47, 7, 1, 0, 0, 0, 48, 50, 5, 1, 0, 0, 49, 51, 5, 2, 0, 0, 50, 49, 1, 0, 0, 0, 50, 51, 1, 0, 0, 0, 51, 56, 1, 0, 0, 0, 52, 54, 5, 3, 0, 0, 53, 55, 5, 2, 0, 0, 54, 53, 1, 0, 0, 0, 54, 55, 1, 0, 0, 0, 55, 57, 1, 0, 0, 0, 56, 52, 1, 0, 0, 0, 57, 58, 1, 0, 0, 0, 58, 56, 1, 0, 0, 0, 58, 59, 1, 0, 0, 0, 59, 9, 1, 0, 0, 0, 13, 12, 16, 18, 23, 26, 29, 32, 35, 38, 44, 50, 54, 58]
|
@ -43,32 +43,33 @@ func configParserInit() {
|
||||
}
|
||||
staticData.PredictionContextCache = antlr.NewPredictionContextCache()
|
||||
staticData.serializedATN = []int32{
|
||||
4, 1, 4, 59, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4,
|
||||
4, 1, 4, 61, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4,
|
||||
1, 0, 1, 0, 3, 0, 13, 8, 0, 1, 0, 1, 0, 3, 0, 17, 8, 0, 3, 0, 19, 8, 0,
|
||||
1, 0, 1, 0, 1, 1, 3, 1, 24, 8, 1, 1, 1, 3, 1, 27, 8, 1, 1, 1, 1, 1, 3,
|
||||
1, 31, 8, 1, 1, 1, 3, 1, 34, 8, 1, 1, 1, 3, 1, 37, 8, 1, 1, 2, 1, 2, 1,
|
||||
3, 1, 3, 3, 3, 43, 8, 3, 1, 3, 1, 3, 1, 4, 1, 4, 3, 4, 49, 8, 4, 1, 4,
|
||||
1, 4, 3, 4, 53, 8, 4, 4, 4, 55, 8, 4, 11, 4, 12, 4, 56, 1, 4, 0, 0, 5,
|
||||
0, 2, 4, 6, 8, 0, 0, 66, 0, 18, 1, 0, 0, 0, 2, 23, 1, 0, 0, 0, 4, 38, 1,
|
||||
0, 0, 0, 6, 42, 1, 0, 0, 0, 8, 46, 1, 0, 0, 0, 10, 19, 3, 2, 1, 0, 11,
|
||||
13, 5, 2, 0, 0, 12, 11, 1, 0, 0, 0, 12, 13, 1, 0, 0, 0, 13, 14, 1, 0, 0,
|
||||
0, 14, 19, 3, 8, 4, 0, 15, 17, 5, 2, 0, 0, 16, 15, 1, 0, 0, 0, 16, 17,
|
||||
1, 0, 0, 0, 17, 19, 1, 0, 0, 0, 18, 10, 1, 0, 0, 0, 18, 12, 1, 0, 0, 0,
|
||||
18, 16, 1, 0, 0, 0, 19, 20, 1, 0, 0, 0, 20, 21, 5, 0, 0, 1, 21, 1, 1, 0,
|
||||
0, 0, 22, 24, 5, 2, 0, 0, 23, 22, 1, 0, 0, 0, 23, 24, 1, 0, 0, 0, 24, 26,
|
||||
1, 0, 0, 0, 25, 27, 3, 4, 2, 0, 26, 25, 1, 0, 0, 0, 26, 27, 1, 0, 0, 0,
|
||||
27, 28, 1, 0, 0, 0, 28, 30, 5, 2, 0, 0, 29, 31, 3, 6, 3, 0, 30, 29, 1,
|
||||
0, 0, 0, 30, 31, 1, 0, 0, 0, 31, 33, 1, 0, 0, 0, 32, 34, 5, 2, 0, 0, 33,
|
||||
32, 1, 0, 0, 0, 33, 34, 1, 0, 0, 0, 34, 36, 1, 0, 0, 0, 35, 37, 3, 8, 4,
|
||||
0, 36, 35, 1, 0, 0, 0, 36, 37, 1, 0, 0, 0, 37, 3, 1, 0, 0, 0, 38, 39, 5,
|
||||
3, 0, 0, 39, 5, 1, 0, 0, 0, 40, 41, 5, 3, 0, 0, 41, 43, 5, 2, 0, 0, 42,
|
||||
40, 1, 0, 0, 0, 42, 43, 1, 0, 0, 0, 43, 44, 1, 0, 0, 0, 44, 45, 5, 3, 0,
|
||||
0, 45, 7, 1, 0, 0, 0, 46, 48, 5, 1, 0, 0, 47, 49, 5, 2, 0, 0, 48, 47, 1,
|
||||
0, 0, 0, 48, 49, 1, 0, 0, 0, 49, 54, 1, 0, 0, 0, 50, 52, 5, 3, 0, 0, 51,
|
||||
53, 5, 2, 0, 0, 52, 51, 1, 0, 0, 0, 52, 53, 1, 0, 0, 0, 53, 55, 1, 0, 0,
|
||||
0, 54, 50, 1, 0, 0, 0, 55, 56, 1, 0, 0, 0, 56, 54, 1, 0, 0, 0, 56, 57,
|
||||
1, 0, 0, 0, 57, 9, 1, 0, 0, 0, 12, 12, 16, 18, 23, 26, 30, 33, 36, 42,
|
||||
48, 52, 56,
|
||||
1, 0, 1, 0, 1, 1, 3, 1, 24, 8, 1, 1, 1, 3, 1, 27, 8, 1, 1, 1, 3, 1, 30,
|
||||
8, 1, 1, 1, 3, 1, 33, 8, 1, 1, 1, 3, 1, 36, 8, 1, 1, 1, 3, 1, 39, 8, 1,
|
||||
1, 2, 1, 2, 1, 3, 1, 3, 3, 3, 45, 8, 3, 1, 3, 1, 3, 1, 4, 1, 4, 3, 4, 51,
|
||||
8, 4, 1, 4, 1, 4, 3, 4, 55, 8, 4, 4, 4, 57, 8, 4, 11, 4, 12, 4, 58, 1,
|
||||
4, 0, 0, 5, 0, 2, 4, 6, 8, 0, 0, 69, 0, 18, 1, 0, 0, 0, 2, 23, 1, 0, 0,
|
||||
0, 4, 40, 1, 0, 0, 0, 6, 44, 1, 0, 0, 0, 8, 48, 1, 0, 0, 0, 10, 19, 3,
|
||||
2, 1, 0, 11, 13, 5, 2, 0, 0, 12, 11, 1, 0, 0, 0, 12, 13, 1, 0, 0, 0, 13,
|
||||
14, 1, 0, 0, 0, 14, 19, 3, 8, 4, 0, 15, 17, 5, 2, 0, 0, 16, 15, 1, 0, 0,
|
||||
0, 16, 17, 1, 0, 0, 0, 17, 19, 1, 0, 0, 0, 18, 10, 1, 0, 0, 0, 18, 12,
|
||||
1, 0, 0, 0, 18, 16, 1, 0, 0, 0, 19, 20, 1, 0, 0, 0, 20, 21, 5, 0, 0, 1,
|
||||
21, 1, 1, 0, 0, 0, 22, 24, 5, 2, 0, 0, 23, 22, 1, 0, 0, 0, 23, 24, 1, 0,
|
||||
0, 0, 24, 26, 1, 0, 0, 0, 25, 27, 3, 4, 2, 0, 26, 25, 1, 0, 0, 0, 26, 27,
|
||||
1, 0, 0, 0, 27, 29, 1, 0, 0, 0, 28, 30, 5, 2, 0, 0, 29, 28, 1, 0, 0, 0,
|
||||
29, 30, 1, 0, 0, 0, 30, 32, 1, 0, 0, 0, 31, 33, 3, 6, 3, 0, 32, 31, 1,
|
||||
0, 0, 0, 32, 33, 1, 0, 0, 0, 33, 35, 1, 0, 0, 0, 34, 36, 5, 2, 0, 0, 35,
|
||||
34, 1, 0, 0, 0, 35, 36, 1, 0, 0, 0, 36, 38, 1, 0, 0, 0, 37, 39, 3, 8, 4,
|
||||
0, 38, 37, 1, 0, 0, 0, 38, 39, 1, 0, 0, 0, 39, 3, 1, 0, 0, 0, 40, 41, 5,
|
||||
3, 0, 0, 41, 5, 1, 0, 0, 0, 42, 43, 5, 3, 0, 0, 43, 45, 5, 2, 0, 0, 44,
|
||||
42, 1, 0, 0, 0, 44, 45, 1, 0, 0, 0, 45, 46, 1, 0, 0, 0, 46, 47, 5, 3, 0,
|
||||
0, 47, 7, 1, 0, 0, 0, 48, 50, 5, 1, 0, 0, 49, 51, 5, 2, 0, 0, 50, 49, 1,
|
||||
0, 0, 0, 50, 51, 1, 0, 0, 0, 51, 56, 1, 0, 0, 0, 52, 54, 5, 3, 0, 0, 53,
|
||||
55, 5, 2, 0, 0, 54, 53, 1, 0, 0, 0, 54, 55, 1, 0, 0, 0, 55, 57, 1, 0, 0,
|
||||
0, 56, 52, 1, 0, 0, 0, 57, 58, 1, 0, 0, 0, 58, 56, 1, 0, 0, 0, 58, 59,
|
||||
1, 0, 0, 0, 59, 9, 1, 0, 0, 0, 13, 12, 16, 18, 23, 26, 29, 32, 35, 38,
|
||||
44, 50, 54, 58,
|
||||
}
|
||||
deserializer := antlr.NewATNDeserializer(nil)
|
||||
staticData.atn = deserializer.Deserialize(staticData.serializedATN)
|
||||
@ -469,18 +470,20 @@ func (p *ConfigParser) Entry() (localctx IEntryContext) {
|
||||
}
|
||||
p.SetState(26)
|
||||
p.GetErrorHandler().Sync(p)
|
||||
if p.HasError() {
|
||||
goto errorExit
|
||||
}
|
||||
_la = p.GetTokenStream().LA(1)
|
||||
|
||||
if _la == ConfigParserSTRING {
|
||||
if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 4, p.GetParserRuleContext()) == 1 {
|
||||
{
|
||||
p.SetState(25)
|
||||
p.Key()
|
||||
}
|
||||
|
||||
} else if p.HasError() { // JIM
|
||||
goto errorExit
|
||||
}
|
||||
p.SetState(29)
|
||||
p.GetErrorHandler().Sync(p)
|
||||
|
||||
if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 5, p.GetParserRuleContext()) == 1 {
|
||||
{
|
||||
p.SetState(28)
|
||||
p.Match(ConfigParserWHITESPACE)
|
||||
@ -489,7 +492,11 @@ func (p *ConfigParser) Entry() (localctx IEntryContext) {
|
||||
goto errorExit
|
||||
}
|
||||
}
|
||||
p.SetState(30)
|
||||
|
||||
} else if p.HasError() { // JIM
|
||||
goto errorExit
|
||||
}
|
||||
p.SetState(32)
|
||||
p.GetErrorHandler().Sync(p)
|
||||
if p.HasError() {
|
||||
goto errorExit
|
||||
@ -498,12 +505,12 @@ func (p *ConfigParser) Entry() (localctx IEntryContext) {
|
||||
|
||||
if _la == ConfigParserSTRING {
|
||||
{
|
||||
p.SetState(29)
|
||||
p.SetState(31)
|
||||
p.Value()
|
||||
}
|
||||
|
||||
}
|
||||
p.SetState(33)
|
||||
p.SetState(35)
|
||||
p.GetErrorHandler().Sync(p)
|
||||
if p.HasError() {
|
||||
goto errorExit
|
||||
@ -512,7 +519,7 @@ func (p *ConfigParser) Entry() (localctx IEntryContext) {
|
||||
|
||||
if _la == ConfigParserWHITESPACE {
|
||||
{
|
||||
p.SetState(32)
|
||||
p.SetState(34)
|
||||
p.Match(ConfigParserWHITESPACE)
|
||||
if p.HasError() {
|
||||
// Recognition error - abort rule
|
||||
@ -521,7 +528,7 @@ func (p *ConfigParser) Entry() (localctx IEntryContext) {
|
||||
}
|
||||
|
||||
}
|
||||
p.SetState(36)
|
||||
p.SetState(38)
|
||||
p.GetErrorHandler().Sync(p)
|
||||
if p.HasError() {
|
||||
goto errorExit
|
||||
@ -530,7 +537,7 @@ func (p *ConfigParser) Entry() (localctx IEntryContext) {
|
||||
|
||||
if _la == ConfigParserHASH {
|
||||
{
|
||||
p.SetState(35)
|
||||
p.SetState(37)
|
||||
p.LeadingComment()
|
||||
}
|
||||
|
||||
@ -624,7 +631,7 @@ func (p *ConfigParser) Key() (localctx IKeyContext) {
|
||||
p.EnterRule(localctx, 4, ConfigParserRULE_key)
|
||||
p.EnterOuterAlt(localctx, 1)
|
||||
{
|
||||
p.SetState(38)
|
||||
p.SetState(40)
|
||||
p.Match(ConfigParserSTRING)
|
||||
if p.HasError() {
|
||||
// Recognition error - abort rule
|
||||
@ -729,12 +736,12 @@ func (p *ConfigParser) Value() (localctx IValueContext) {
|
||||
localctx = NewValueContext(p, p.GetParserRuleContext(), p.GetState())
|
||||
p.EnterRule(localctx, 6, ConfigParserRULE_value)
|
||||
p.EnterOuterAlt(localctx, 1)
|
||||
p.SetState(42)
|
||||
p.SetState(44)
|
||||
p.GetErrorHandler().Sync(p)
|
||||
|
||||
if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 8, p.GetParserRuleContext()) == 1 {
|
||||
if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 9, p.GetParserRuleContext()) == 1 {
|
||||
{
|
||||
p.SetState(40)
|
||||
p.SetState(42)
|
||||
p.Match(ConfigParserSTRING)
|
||||
if p.HasError() {
|
||||
// Recognition error - abort rule
|
||||
@ -742,7 +749,7 @@ func (p *ConfigParser) Value() (localctx IValueContext) {
|
||||
}
|
||||
}
|
||||
{
|
||||
p.SetState(41)
|
||||
p.SetState(43)
|
||||
p.Match(ConfigParserWHITESPACE)
|
||||
if p.HasError() {
|
||||
// Recognition error - abort rule
|
||||
@ -754,7 +761,7 @@ func (p *ConfigParser) Value() (localctx IValueContext) {
|
||||
goto errorExit
|
||||
}
|
||||
{
|
||||
p.SetState(44)
|
||||
p.SetState(46)
|
||||
p.Match(ConfigParserSTRING)
|
||||
if p.HasError() {
|
||||
// Recognition error - abort rule
|
||||
@ -872,14 +879,14 @@ func (p *ConfigParser) LeadingComment() (localctx ILeadingCommentContext) {
|
||||
|
||||
p.EnterOuterAlt(localctx, 1)
|
||||
{
|
||||
p.SetState(46)
|
||||
p.SetState(48)
|
||||
p.Match(ConfigParserHASH)
|
||||
if p.HasError() {
|
||||
// Recognition error - abort rule
|
||||
goto errorExit
|
||||
}
|
||||
}
|
||||
p.SetState(48)
|
||||
p.SetState(50)
|
||||
p.GetErrorHandler().Sync(p)
|
||||
if p.HasError() {
|
||||
goto errorExit
|
||||
@ -888,7 +895,7 @@ func (p *ConfigParser) LeadingComment() (localctx ILeadingCommentContext) {
|
||||
|
||||
if _la == ConfigParserWHITESPACE {
|
||||
{
|
||||
p.SetState(47)
|
||||
p.SetState(49)
|
||||
p.Match(ConfigParserWHITESPACE)
|
||||
if p.HasError() {
|
||||
// Recognition error - abort rule
|
||||
@ -897,7 +904,7 @@ func (p *ConfigParser) LeadingComment() (localctx ILeadingCommentContext) {
|
||||
}
|
||||
|
||||
}
|
||||
p.SetState(54)
|
||||
p.SetState(56)
|
||||
p.GetErrorHandler().Sync(p)
|
||||
if p.HasError() {
|
||||
goto errorExit
|
||||
@ -906,14 +913,14 @@ func (p *ConfigParser) LeadingComment() (localctx ILeadingCommentContext) {
|
||||
|
||||
for ok := true; ok; ok = _la == ConfigParserSTRING {
|
||||
{
|
||||
p.SetState(50)
|
||||
p.SetState(52)
|
||||
p.Match(ConfigParserSTRING)
|
||||
if p.HasError() {
|
||||
// Recognition error - abort rule
|
||||
goto errorExit
|
||||
}
|
||||
}
|
||||
p.SetState(52)
|
||||
p.SetState(54)
|
||||
p.GetErrorHandler().Sync(p)
|
||||
if p.HasError() {
|
||||
goto errorExit
|
||||
@ -922,7 +929,7 @@ func (p *ConfigParser) LeadingComment() (localctx ILeadingCommentContext) {
|
||||
|
||||
if _la == ConfigParserWHITESPACE {
|
||||
{
|
||||
p.SetState(51)
|
||||
p.SetState(53)
|
||||
p.Match(ConfigParserWHITESPACE)
|
||||
if p.HasError() {
|
||||
// Recognition error - abort rule
|
||||
@ -932,7 +939,7 @@ func (p *ConfigParser) LeadingComment() (localctx ILeadingCommentContext) {
|
||||
|
||||
}
|
||||
|
||||
p.SetState(56)
|
||||
p.SetState(58)
|
||||
p.GetErrorHandler().Sync(p)
|
||||
if p.HasError() {
|
||||
goto errorExit
|
||||
|
@ -157,6 +157,62 @@ Match 192.168.0.2
|
||||
if !(sixthEntry.Key.Value == "MaxAuthTries" && sixthEntry.OptionValue.Value == "3") {
|
||||
t.Errorf("Expected sixth entry to be 'MaxAuthTries 3', but got: %v", sixthEntry.Value)
|
||||
}
|
||||
|
||||
firstOption, firstMatchBlock := p.FindOption(uint32(4))
|
||||
|
||||
if !(firstOption.Key.Value == "PasswordAuthentication" && firstOption.OptionValue.Value == "yes" && firstMatchBlock.MatchEntry.Value == "Match 192.168.0.1") {
|
||||
t.Errorf("Expected first option to be 'PasswordAuthentication yes' and first match block to be 'Match 192.168.0.1', but got: %v, %v", firstOption, firstMatchBlock)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSimpleExampleWithComments(
|
||||
t *testing.T,
|
||||
) {
|
||||
input := utils.Dedent(`
|
||||
# Test
|
||||
PermitRootLogin no
|
||||
Port 22
|
||||
# Second test
|
||||
AddressFamily any
|
||||
Sample
|
||||
`)
|
||||
p := NewSSHConfig()
|
||||
errors := p.Parse(input)
|
||||
|
||||
if len(errors) != 0 {
|
||||
t.Fatalf("Expected no errors, got %v", errors)
|
||||
}
|
||||
|
||||
if !(p.Options.Size() == 4 &&
|
||||
len(utils.KeysOfMap(p.CommentLines)) == 2) {
|
||||
t.Errorf("Expected 3 options and 2 comment lines, but got: %v, %v", p.Options, p.CommentLines)
|
||||
}
|
||||
|
||||
rawFirstEntry, _ := p.Options.Get(uint32(1))
|
||||
firstEntry := rawFirstEntry.(*SSHOption)
|
||||
if !(firstEntry.Value == "PermitRootLogin no") {
|
||||
t.Errorf("Expected first entry to be 'PermitRootLogin no', but got: %v", firstEntry.Value)
|
||||
}
|
||||
|
||||
if len(p.CommentLines) != 2 {
|
||||
t.Errorf("Expected 2 comment lines, but got: %v", p.CommentLines)
|
||||
}
|
||||
|
||||
if !utils.KeyExists(p.CommentLines, uint32(0)) {
|
||||
t.Errorf("Expected comment line 0 to not exist, but it does")
|
||||
}
|
||||
|
||||
if !(utils.KeyExists(p.CommentLines, uint32(3))) {
|
||||
t.Errorf("Expected comment line 2 to exist, but it does not")
|
||||
}
|
||||
|
||||
rawSecondEntry, _ := p.Options.Get(uint32(5))
|
||||
secondEntry := rawSecondEntry.(*SSHOption)
|
||||
|
||||
if !(secondEntry.Value == "Sample") {
|
||||
t.Errorf("Expected second entry to be 'Sample', but got: %v", secondEntry.Value)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestComplexExample(
|
||||
|
@ -57,3 +57,41 @@ type SSHConfig struct {
|
||||
// [uint32]{} -> line number -> {}
|
||||
CommentLines map[uint32]struct{}
|
||||
}
|
||||
|
||||
func (c SSHConfig) FindMatchBlock(line uint32) *SSHMatchBlock {
|
||||
for currentLine := line; currentLine > 0; currentLine-- {
|
||||
rawEntry, found := c.Options.Get(currentLine)
|
||||
|
||||
if !found {
|
||||
continue
|
||||
}
|
||||
|
||||
switch entry := rawEntry.(type) {
|
||||
case *SSHMatchBlock:
|
||||
return entry
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c SSHConfig) FindOption(line uint32) (*SSHOption, *SSHMatchBlock) {
|
||||
matchBlock := c.FindMatchBlock(line)
|
||||
|
||||
if matchBlock != nil {
|
||||
rawEntry, found := matchBlock.Options.Get(line)
|
||||
|
||||
if found {
|
||||
return rawEntry.(*SSHOption), matchBlock
|
||||
}
|
||||
}
|
||||
|
||||
rawEntry, found := c.Options.Get(line)
|
||||
|
||||
if found {
|
||||
return rawEntry.(*SSHOption), nil
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ var Options = map[string]docvalues.Value{
|
||||
Documentation: `This keyword can be followed by a list of group name patterns, separated by spaces. If specified, login is allowed only for users whose primary group or supplementary group list matches one of the patterns. Only group names are valid; a numerical group ID is not recognized. By default, login is allowed for all groups. The allow/deny groups directives are processed in the following order: DenyGroups, AllowGroups.
|
||||
|
||||
See PATTERNS in ssh_config(5) for more information on patterns. This keyword may appear multiple times in sshd_config with each instance appending to the list.`,
|
||||
Value: docvalues.GroupValue(" ", false),
|
||||
Value: docvalues.GroupValue(" ", false),
|
||||
},
|
||||
"AllowStreamLocalForwarding": docvalues.DocumentationValue{
|
||||
Documentation: `Specifies whether StreamLocal (Unix-domain socket) forwarding is permitted. The available options are yes (the default) or all to allow StreamLocal forwarding, no to prevent all StreamLocal forwarding, local to allow local (from the perspective of ssh(1)) forwarding only or remote to allow remote forwarding only. Note that disabling StreamLocal forwarding does not improve security unless users are also denied shell access, as they can always install their own forwarders.`,
|
||||
|
35
handlers/sshd_config/handlers/completions.go
Normal file
35
handlers/sshd_config/handlers/completions.go
Normal file
@ -0,0 +1,35 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
docvalues "config-lsp/doc-values"
|
||||
sshdconfig "config-lsp/handlers/sshd_config"
|
||||
"config-lsp/handlers/sshd_config/ast"
|
||||
"config-lsp/handlers/sshd_config/fields"
|
||||
"config-lsp/utils"
|
||||
|
||||
protocol "github.com/tliron/glsp/protocol_3_16"
|
||||
)
|
||||
|
||||
func GetRootCompletions(
|
||||
d *sshdconfig.SSHDocument,
|
||||
parentMatchBlock *ast.SSHMatchBlock,
|
||||
) ([]protocol.CompletionItem, error) {
|
||||
kind := protocol.CompletionItemKindField
|
||||
format := protocol.InsertTextFormatSnippet
|
||||
|
||||
return utils.MapMapToSlice(
|
||||
fields.Options,
|
||||
func(name string, rawValue docvalues.Value) protocol.CompletionItem {
|
||||
doc := rawValue.(docvalues.DocumentationValue)
|
||||
|
||||
insertText := name + " " + "${1:value}"
|
||||
return protocol.CompletionItem{
|
||||
Label: name,
|
||||
Kind: &kind,
|
||||
Documentation: doc.Documentation,
|
||||
InsertText: &insertText,
|
||||
InsertTextFormat: &format,
|
||||
}
|
||||
},
|
||||
), nil
|
||||
}
|
@ -1,10 +1,33 @@
|
||||
package lsp
|
||||
|
||||
import (
|
||||
sshdconfig "config-lsp/handlers/sshd_config"
|
||||
"config-lsp/handlers/sshd_config/handlers"
|
||||
|
||||
"github.com/tliron/glsp"
|
||||
protocol "github.com/tliron/glsp/protocol_3_16"
|
||||
)
|
||||
|
||||
func TextDocumentCompletion(context *glsp.Context, params *protocol.CompletionParams) (any, error) {
|
||||
line := params.Position.Line
|
||||
cursor := params.Position.Character
|
||||
_ = cursor
|
||||
|
||||
d := sshdconfig.DocumentParserMap[params.TextDocument.URI]
|
||||
|
||||
if _, found := d.Config.CommentLines[line]; found {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
entry, matchBlock := d.Config.FindOption(line)
|
||||
|
||||
if entry == nil {
|
||||
// Empty line
|
||||
return handlers.GetRootCompletions(
|
||||
d,
|
||||
matchBlock,
|
||||
)
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
@ -2,8 +2,8 @@ package lsp
|
||||
|
||||
import (
|
||||
"config-lsp/common"
|
||||
"config-lsp/handlers/sshd_config/analyzer"
|
||||
"config-lsp/handlers/sshd_config"
|
||||
"config-lsp/handlers/sshd_config/analyzer"
|
||||
"config-lsp/utils"
|
||||
|
||||
"github.com/tliron/glsp"
|
||||
|
@ -11,4 +11,3 @@ type SSHDocument struct {
|
||||
}
|
||||
|
||||
var DocumentParserMap = map[protocol.DocumentUri]*SSHDocument{}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user