github.com/cnboonhan/delve@v0.0.0-20230908061759-363f2388c2fb/service/dap/command.go (about) 1 package dap 2 3 import ( 4 "bytes" 5 "errors" 6 "fmt" 7 "sort" 8 "strings" 9 10 "github.com/go-delve/delve/pkg/config" 11 "github.com/google/go-dap" 12 ) 13 14 func (s *Session) delveCmd(goid, frame int, cmdstr string) (string, error) { 15 vals := strings.SplitN(strings.TrimSpace(cmdstr), " ", 2) 16 cmdname := vals[0] 17 var args string 18 if len(vals) > 1 { 19 args = strings.TrimSpace(vals[1]) 20 } 21 for _, cmd := range debugCommands(s) { 22 for _, alias := range cmd.aliases { 23 if alias == cmdname { 24 return cmd.cmdFn(goid, frame, args) 25 } 26 } 27 } 28 return "", errNoCmd 29 } 30 31 type cmdfunc func(goid, frame int, args string) (string, error) 32 33 type command struct { 34 aliases []string 35 helpMsg string 36 cmdFn cmdfunc 37 } 38 39 const ( 40 msgHelp = `Prints the help message. 41 42 dlv help [command] 43 44 Type "help" followed by the name of a command for more information about it.` 45 46 msgConfig = `Changes configuration parameters. 47 48 dlv config -list 49 50 Show all configuration parameters. 51 52 dlv config -list <parameter> 53 54 Show value of a configuration parameter. 55 56 dlv config <parameter> <value> 57 58 Changes the value of a configuration parameter. 59 60 dlv config substitutePath <from> <to> 61 dlv config substitutePath <from> 62 dlv config substitutePath -clear 63 64 Adds or removes a path substitution rule. If -clear is used all substitutePath rules are removed. 65 See also Documentation/cli/substitutepath.md.` 66 msgSources = `Print list of source files. 67 68 dlv sources [<regex>] 69 70 If regex is specified only the source files matching it will be returned.` 71 ) 72 73 // debugCommands returns a list of commands with default commands defined. 74 func debugCommands(s *Session) []command { 75 return []command{ 76 {aliases: []string{"help", "h"}, cmdFn: s.helpMessage, helpMsg: msgHelp}, 77 {aliases: []string{"config"}, cmdFn: s.evaluateConfig, helpMsg: msgConfig}, 78 {aliases: []string{"sources", "s"}, cmdFn: s.sources, helpMsg: msgSources}, 79 } 80 } 81 82 var errNoCmd = errors.New("command not available") 83 84 func (s *Session) helpMessage(_, _ int, args string) (string, error) { 85 var buf bytes.Buffer 86 if args != "" { 87 for _, cmd := range debugCommands(s) { 88 for _, alias := range cmd.aliases { 89 if alias == args { 90 return cmd.helpMsg, nil 91 } 92 } 93 } 94 return "", errNoCmd 95 } 96 97 fmt.Fprintln(&buf, "The following commands are available:") 98 99 for _, cmd := range debugCommands(s) { 100 h := cmd.helpMsg 101 if idx := strings.Index(h, "\n"); idx >= 0 { 102 h = h[:idx] 103 } 104 if len(cmd.aliases) > 1 { 105 fmt.Fprintf(&buf, " dlv %s (alias: %s) \t %s\n", cmd.aliases[0], strings.Join(cmd.aliases[1:], " | "), h) 106 } else { 107 fmt.Fprintf(&buf, " dlv %s \t %s\n", cmd.aliases[0], h) 108 } 109 } 110 111 fmt.Fprintln(&buf) 112 fmt.Fprintln(&buf, "Type 'dlv help' followed by a command for full documentation.") 113 return buf.String(), nil 114 } 115 116 func (s *Session) evaluateConfig(_, _ int, expr string) (string, error) { 117 argv := config.Split2PartsBySpace(expr) 118 name := argv[0] 119 if name == "-list" { 120 if len(argv) > 1 { 121 return config.ConfigureListByName(&s.args, argv[1], "cfgName"), nil 122 } 123 return listConfig(&s.args), nil 124 } 125 updated, res, err := configureSet(&s.args, expr) 126 if err != nil { 127 return "", err 128 } 129 130 if updated { 131 // Send invalidated events for areas that are affected by configuration changes. 132 switch name { 133 case "showGlobalVariables", "showRegisters": 134 // Variable data has become invalidated. 135 s.send(&dap.InvalidatedEvent{ 136 Event: *newEvent("invalidated"), 137 Body: dap.InvalidatedEventBody{ 138 Areas: []dap.InvalidatedAreas{"variables"}, 139 }, 140 }) 141 case "goroutineFilters", "hideSystemGoroutines": 142 // Thread related data has become invalidated. 143 s.send(&dap.InvalidatedEvent{ 144 Event: *newEvent("invalidated"), 145 Body: dap.InvalidatedEventBody{ 146 Areas: []dap.InvalidatedAreas{"threads"}, 147 }, 148 }) 149 } 150 res += "\nUpdated" 151 } 152 return res, nil 153 } 154 155 func (s *Session) sources(_, _ int, filter string) (string, error) { 156 sources, err := s.debugger.Sources(filter) 157 if err != nil { 158 return "", err 159 } 160 sort.Strings(sources) 161 return strings.Join(sources, "\n"), nil 162 }