Commit bf358dda authored by Kevin Lyda's avatar Kevin Lyda
Browse files

Complete folder names

parent c6d0de79
Loading
Loading
Loading
Loading
+37 −4
Original line number Diff line number Diff line
@@ -10,25 +10,34 @@ import (
type Completer struct {
	commands      []string
	flags         map[string]FlagTable
	argCompleters map[string]CompleterFunc
}

// NewCompleter creates a new completer from a CommandTable.
func NewCompleter(ct CommandTable) Completer {
	comps := []string{}
	flags := map[string]FlagTable{}
	argCompleters := map[string]CompleterFunc{}
	for _, entry := range ct {
		comps = append(comps, entry.Name)
		flags[entry.Name] = entry.Command.FlagTable
		if entry.Command.Completer != nil {
			argCompleters[entry.Name] = entry.Command.Completer
		}
		for _, sub := range entry.Command.CommandTable {
			fullc := entry.Name + " " + sub.Name
			comps = append(comps, fullc)
			flags[fullc] = sub.Command.FlagTable
			if sub.Command.Completer != nil {
				argCompleters[fullc] = sub.Command.Completer
			}
		}
	}
	sort.Strings(comps)
	return Completer{
		commands:      comps,
		flags:         flags,
		argCompleters: argCompleters,
	}
}

@@ -70,6 +79,30 @@ func (c Completer) Do(line []rune, pos int) ([][]rune, int) {
		}
	}

	// Check if the user is typing an argument after a complete command.
	if spaceIdx := strings.LastIndex(input, " "); spaceIdx >= 0 {
		cmdPart := strings.TrimSpace(input[:spaceIdx])
		argPart := input[spaceIdx+1:]
		cmdKey := strings.ToUpper(cmdPart)
		argUpper := strings.ToUpper(argPart)

		if completer, ok := c.argCompleters[cmdKey]; ok {
			choices := completer()
			newline := [][]rune{}
			for _, choice := range choices {
				if strings.HasPrefix(strings.ToUpper(choice), argUpper) {
					rest := choice[len(argPart):]
					if lower {
						newline = append(newline, []rune(strings.ToLower(rest)))
					} else {
						newline = append(newline, []rune(rest))
					}
				}
			}
			return newline, pos
		}
	}

	// Command partially typed in.
	newline := [][]rune{}
	for i := range c.commands {
+4 −3
Original line number Diff line number Diff line
@@ -939,6 +939,7 @@ message.`,
		MinArgs:   1,
		MaxArgs:   1,
		Action:    ActionSelect,
		Completer: completeFolderNames,
		Flags: dclish.Flags{
			"/MARKED": {
				Description: `  Selects  only messages that have been marked (indicated by an asterisk).
+13 −0
Original line number Diff line number Diff line
@@ -142,6 +142,19 @@ func ActionCreate(cmd *dclish.Command) error {
	return err
}

// completeFolderNames returns folder names for tab completion.
func completeFolderNames() []string {
	folderList, err := folders.ListFolder()
	if err != nil {
		return nil
	}
	names := make([]string, len(folderList))
	for i, f := range folderList {
		names[i] = f.Name
	}
	return names
}

// ActionSelect handles the `SELECT` command.  This selects a folder.
//
// This is based on `SELECT_FOLDER` in bulletin5.for.
+22 −0
Original line number Diff line number Diff line
@@ -26,6 +26,28 @@ func ActionDirectory(cmd *dclish.Command) error {
	if cmd.Flags["/EXPIRATION"].Value == "true" {
		showExpiration = true
	}
	if cmd.Flags["/FOLDERS"].Value == "true" {
		folderList, err := folders.ListFolder()
		if err != nil {
			return err
		}
		if len(folderList) == 0 {
			fmt.Println("There are no folders.")
			return nil
		}
		showDesc := cmd.Flags["/DESCRIBE"].Value == "true"
		buf := strings.Builder{}
		buf.WriteString(fmt.Sprintf("%-25s %5s\n", "Folder", "Msgs"))
		for _, f := range folderList {
			buf.WriteString(fmt.Sprintf("%-25s %5d", f.Name, f.Count))
			if showDesc && f.Description != "" {
				buf.WriteString(fmt.Sprintf("  %s", f.Description))
			}
			buf.WriteString("\n")
		}
		pager.Pager(buf.String())
		return nil
	}
	if len(cmd.Args) == 1 {
		folder, err := folders.ValidFolder(cmd.Args[0])
		if err != nil {