package edit

import (
	

	
	
	
	
	
	
	
	
	
	
)

func ( *Editor,  *eval.Evaler,  store.Store,  histutil.Store,  eval.NsBuilder) {
	 := newBindingVar(emptyBindingsMap)
	 := .app
	.AddNs("listing",
		eval.NsBuilder{
			"binding": ,
		}.AddGoFns("<edit:listing>:", map[string]interface{}{
			"accept":       func() { listingAccept() },
			"accept-close": func() { listingAcceptClose() },
			"up":           func() { listingUp() },
			"down":         func() { listingDown() },
			"up-cycle":     func() { listingUpCycle() },
			"down-cycle":   func() { listingDownCycle() },
			"page-up":      func() { listingPageUp() },
			"page-down":    func() { listingPageDown() },
			"start-custom": func( *eval.Frame,  customListingOpts,  interface{}) {
				listingStartCustom(, , , )
			},
			/*
				"toggle-filtering": cli.ListingToggleFiltering,
			*/
		}).Ns())

	initHistlist(, , , , )
	initLastcmd(, , , , )
	initLocation(, , , , )
}

var filterSpec = mode.FilterSpec{
	Maker: func( string) func(string) bool {
		,  := filter.Compile()
		if  == nil {
			return func(string) bool { return true }
		}
		return .Match
	},
	Highlighter: filter.Highlight,
}

func ( *Editor,  *eval.Evaler,  histutil.Store,  vars.PtrVar,  eval.NsBuilder) {
	 := newBindingVar(emptyBindingsMap)
	 := newMapBindings(, , , )
	 := newBoolVar(true)
	.AddNs("histlist",
		eval.NsBuilder{
			"binding": ,
		}.AddGoFns("<edit:histlist>", map[string]interface{}{
			"start": func() {
				,  := mode.NewHistlist(.app, mode.HistlistSpec{
					Bindings: ,
					AllCmds:  .AllCmds,
					Dedup: func() bool {
						return .Get().(bool)
					},
					Filter: filterSpec,
				})
				startMode(.app, , )
			},
			"toggle-dedup": func() {
				.Set(!.Get().(bool))
				listingRefilter(.app)
				.app.Redraw()
			},
		}).Ns())
}

func ( *Editor,  *eval.Evaler,  histutil.Store,  vars.PtrVar,  eval.NsBuilder) {
	 := newBindingVar(emptyBindingsMap)
	 := newMapBindings(, , , )
	.AddNs("lastcmd",
		eval.NsBuilder{
			"binding": ,
		}.AddGoFn("<edit:lastcmd>", "start", func() {
			// TODO: Specify wordifier
			,  := mode.NewLastcmd(.app, mode.LastcmdSpec{
				Bindings: , Store: })
			startMode(.app, , )
		}).Ns())
}

func ( *Editor,  *eval.Evaler,  store.Store,  vars.PtrVar,  eval.NsBuilder) {
	 := newBindingVar(emptyBindingsMap)
	 := newListVar(vals.EmptyList)
	 := newListVar(vals.EmptyList)
	 := newMapVar(vals.EmptyMap)

	 := newMapBindings(, , , )
	 := mode.LocationWSIterator(
		adaptToIterateStringPair())

	.AddNs("location",
		eval.NsBuilder{
			"binding":    ,
			"hidden":     ,
			"pinned":     ,
			"workspaces": ,
		}.AddGoFn("<edit:location>", "start", func() {
			,  := mode.NewLocation(.app, mode.LocationSpec{
				Bindings: , Store: dirStore{, },
				IteratePinned:     adaptToIterateString(),
				IterateHidden:     adaptToIterateString(),
				IterateWorkspaces: ,
				Filter:            filterSpec,
			})
			startMode(.app, , )
		}).Ns())
	.AddAfterChdir(func(string) {
		,  := os.Getwd()
		if  != nil {
			// TODO(xiaq): Surface the error.
			return
		}
		.AddDir(, 1)
		,  := .Parse()
		if  != "" {
			.AddDir(+[len():], 1)
		}
	})
}

//elvdoc:fn listing:accept
//
// Accepts the current selected listing item.

func ( cli.App) {
	,  := .CopyState().Addon.(tk.ComboBox)
	if ! {
		return
	}
	.ListBox().Accept()
}

//elvdoc:fn listing:accept-close
//
// Accepts the current selected listing item and closes the listing.

func ( cli.App) {
	listingAccept()
	closeMode()
}

//elvdoc:fn listing:up
//
// Moves the cursor up in listing mode.

func ( cli.App) { listingSelect(, tk.Prev) }

//elvdoc:fn listing:down
//
// Moves the cursor down in listing mode.

func ( cli.App) { listingSelect(, tk.Next) }

//elvdoc:fn listing:up-cycle
//
// Moves the cursor up in listing mode, or to the last item if the first item is
// currently selected.

func ( cli.App) { listingSelect(, tk.PrevWrap) }

//elvdoc:fn listing:down-cycle
//
// Moves the cursor down in listing mode, or to the first item if the last item is
// currently selected.

func ( cli.App) { listingSelect(, tk.NextWrap) }

//elvdoc:fn listing:page-up
//
// Moves the cursor up one page.

func ( cli.App) { listingSelect(, tk.PrevPage) }

//elvdoc:fn listing:page-down
//
// Moves the cursor down one page.

func ( cli.App) { listingSelect(, tk.NextPage) }

//elvdoc:fn listing:left
//
// Moves the cursor left in listing mode.

func ( cli.App) { listingSelect(, tk.Left) }

//elvdoc:fn listing:right
//
// Moves the cursor right in listing mode.

func ( cli.App) { listingSelect(, tk.Right) }

func ( cli.App,  func(tk.ListBoxState) int) {
	,  := .CopyState().Addon.(tk.ComboBox)
	if ! {
		return
	}
	.ListBox().Select()
}

func ( cli.App) {
	,  := .CopyState().Addon.(tk.ComboBox)
	if ! {
		return
	}
	.Refilter()
}

//elvdoc:var location:hidden
//
// A list of directories to hide in the location addon.

//elvdoc:var location:pinned
//
// A list of directories to always show at the top of the list of the location
// addon.

//elvdoc:var location:workspaces
//
// A map mapping types of workspaces to their patterns.

func ( vars.Var) func(func(string)) {
	return func( func( string)) {
		vals.Iterate(.Get(), func( interface{}) bool {
			(vals.ToString())
			return true
		})
	}
}

func ( vars.Var) func(func(string, string) bool) {
	return func( func(,  string) bool) {
		 := .Get().(hashmap.Map)
		for  := .Iterator(); .HasElem(); .Next() {
			,  := .Elem()
			,  := .(string)
			,  := .(string)
			if  &&  {
				 := (, )
				if ! {
					break
				}
			}
		}
	}
}

// Wraps an Evaler to implement the cli.DirStore interface.
type dirStore struct {
	ev *eval.Evaler
	st store.Store
}

func ( dirStore) ( string) error {
	return .ev.Chdir()
}

func ( dirStore) ( map[string]struct{}) ([]store.Dir, error) {
	return .st.Dirs()
}

func ( dirStore) () (string, error) {
	return os.Getwd()
}

func ( cli.App,  tk.Widget,  error) {
	if  != nil {
		.SetAddon(, false)
		.Redraw()
	}
	if  != nil {
		.Notify(.Error())
	}
}