gitlab.com/Raven-IO/raven-delve@v1.22.4/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/google/go-dap"
    11  	"gitlab.com/Raven-IO/raven-delve/pkg/config"
    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  
    67  	dlv config showPprofLabels <label>
    68  	dlv config showPprofLabels -clear <label>
    69  	dlv config showPprofLabels -clear
    70  
    71  		Adds or removes a label key to show in the callstack view. If -clear is used without an argument,
    72  		all labels are removed.`
    73  	msgSources = `Print list of source files.
    74  
    75  	dlv sources [<regex>]
    76  
    77  If regex is specified only the source files matching it will be returned.`
    78  )
    79  
    80  // debugCommands returns a list of commands with default commands defined.
    81  func debugCommands(s *Session) []command {
    82  	return []command{
    83  		{aliases: []string{"help", "h"}, cmdFn: s.helpMessage, helpMsg: msgHelp},
    84  		{aliases: []string{"config"}, cmdFn: s.evaluateConfig, helpMsg: msgConfig},
    85  		{aliases: []string{"sources", "s"}, cmdFn: s.sources, helpMsg: msgSources},
    86  	}
    87  }
    88  
    89  var errNoCmd = errors.New("command not available")
    90  
    91  func (s *Session) helpMessage(_, _ int, args string) (string, error) {
    92  	var buf bytes.Buffer
    93  	if args != "" {
    94  		for _, cmd := range debugCommands(s) {
    95  			for _, alias := range cmd.aliases {
    96  				if alias == args {
    97  					return cmd.helpMsg, nil
    98  				}
    99  			}
   100  		}
   101  		return "", errNoCmd
   102  	}
   103  
   104  	fmt.Fprintln(&buf, "The following commands are available:")
   105  
   106  	for _, cmd := range debugCommands(s) {
   107  		h := cmd.helpMsg
   108  		if idx := strings.Index(h, "\n"); idx >= 0 {
   109  			h = h[:idx]
   110  		}
   111  		if len(cmd.aliases) > 1 {
   112  			fmt.Fprintf(&buf, "    dlv %s (alias: %s) \t %s\n", cmd.aliases[0], strings.Join(cmd.aliases[1:], " | "), h)
   113  		} else {
   114  			fmt.Fprintf(&buf, "    dlv %s \t %s\n", cmd.aliases[0], h)
   115  		}
   116  	}
   117  
   118  	fmt.Fprintln(&buf)
   119  	fmt.Fprintln(&buf, "Type 'dlv help' followed by a command for full documentation.")
   120  	return buf.String(), nil
   121  }
   122  
   123  func (s *Session) evaluateConfig(_, _ int, expr string) (string, error) {
   124  	argv := config.Split2PartsBySpace(expr)
   125  	name := argv[0]
   126  	if name == "-list" {
   127  		if len(argv) > 1 {
   128  			return config.ConfigureListByName(&s.args, argv[1], "cfgName"), nil
   129  		}
   130  		return listConfig(&s.args), nil
   131  	}
   132  	updated, res, err := configureSet(&s.args, expr)
   133  	if err != nil {
   134  		return "", err
   135  	}
   136  
   137  	if updated {
   138  		// Send invalidated events for areas that are affected by configuration changes.
   139  		switch name {
   140  		case "showGlobalVariables", "showRegisters":
   141  			// Variable data has become invalidated.
   142  			s.send(&dap.InvalidatedEvent{
   143  				Event: *newEvent("invalidated"),
   144  				Body: dap.InvalidatedEventBody{
   145  					Areas: []dap.InvalidatedAreas{"variables"},
   146  				},
   147  			})
   148  		case "goroutineFilters", "hideSystemGoroutines", "showPprofLabels":
   149  			// Thread related data has become invalidated.
   150  			s.send(&dap.InvalidatedEvent{
   151  				Event: *newEvent("invalidated"),
   152  				Body: dap.InvalidatedEventBody{
   153  					Areas: []dap.InvalidatedAreas{"threads"},
   154  				},
   155  			})
   156  		}
   157  		res += "\nUpdated"
   158  	}
   159  	return res, nil
   160  }
   161  
   162  func (s *Session) sources(_, _ int, filter string) (string, error) {
   163  	sources, err := s.debugger.Sources(filter)
   164  	if err != nil {
   165  		return "", err
   166  	}
   167  	sort.Strings(sources)
   168  	return strings.Join(sources, "\n"), nil
   169  }