peco

package module
v0.2.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 15, 2014 License: MIT Imports: 20 Imported by: 0

README

peco

Simplistic interactive filtering tool

Description

peco is based on percol. The idea is that percol was darn useful, but I wanted a tool that was a single binary. peco is written in Go, and as of this writing only implements the basic filtering feature (mainly because that's the only thing I use -- you're welcome to send me pull requests to make peco more compatible with percol).

peco can be a great tool to filter stuff like logs, process stats, find files, because unlike grep, you can type as you think and look through the current results.

For basic usage, continue down below. For more cool elaborate usage samples, please see the wiki, and if you have any other tricks you want to share, please add to it!

Demo

Demos speak more than a thousand words! Here's me looking for a process on my mac. As you can see, you can page through your results, and you can keep changing the query:

optimized

Here's me trying to figure out which file to open:

optimized

When you combine tools like zsh, peco, and ghq, you can make managing/moving around your huge dev area a piece of cake! (this example doesn't use zsh functions so you can see what I'm doing)

optimized

Features

Search results are filtered as you type. This is great to drill down to the line you are looking for

Multiple terms turn the query into an "AND" query:

optimized

When you find that line that you want, press enter, and the resulting line is printed to stdout, which allows you to pipe it to other tools

Select Multiple Lines

You can select multiple lines!

optimized

Select Range Of Lines

Not only can you select multiple lines one by one, you can select a range of lines

optimized

Select Matchers

Different types of matchers are available. Default is case-insensitive matcher, so lines with any case will match. You can toggle between IgnoreCase, CaseSensitive, and RegExp matchers. The RegExp matcher allows you to use any valid regular expression to match lines

optimized

Works on Windows!

I have been told that peco even works on windows :)

Installation

Just want the binary?

Go to the releases page, find the version you want, and download the zip file. Unpack the zip file, and put the binary to somewhere you want (on UNIX-y systems, /usr/local/bin or the like). Make sure it has execution bits turned on. Yes, it is a single binary! You can put it anywhere you want :)

THIS IS THE RECOMMENDED WAY (except for OS X homebrew users)

Mac OS X / Homebrew

If you're on OS X and want to use homebrew, use my custom tap:

brew tap peco/peco
brew install peco

optimized

go get

If you want to go the Go way (install in GOPATH/bin) and just want the command:

go get github.com/peco/peco/cmd/peco

Command Line Options

-h, --help

Display a help message

--version

Display the version of peco

--query

Specifies the default query to be used upon startup. This is useful for scripts and functions where you can figure out before hand what the most likely query string is.

--rcfile

Pass peco a configuration file, which currently must be a JSON file. If unspecified it will try a series of files by default. See Configuration File for the actual locationes searched.

-b, --buffer-size

Limits the buffer size to num. This is an important feature when you are using peco against a possibbly infinite stream, as it limits the number of lines that peco holds at any given time, preventing it from exhausting all the memory. By default the buffer size is unlimited.

--null

WARNING: EXPERIMENTAL. This feature will probably stay, but the option name may change in the future.

Changes how peco interprets incoming data. When this flag is set, you may insert NUL ('\0') characters in your input. Anything before the NUL character is treated as the string to be displaed by peco and is used for matching against user query. Anything after the NUL character is used as the "result": i.e., when peco is about to exit, it displays this string instead of the original string displayed.

Here's a simple example of how to use this feature

--no-ignore-case

By default peco starts in case insensitive mode. When this option is specified, peco will start in case sensitive mode. This can be toggled while peco is still in session.

--initial-index

Specifies the initial line position upon start up. E.g. If you want to start out with the second line selected, set it to "1" (because the index is 0 based)

--prompt

Specifies the query line's prompt string. When specified, takes precedence over the configuration file's Prompt section. The default value is QUERY>

Configuration File

peco by default consults a few locations for the config files.

  1. Location specified in --rcfile. If this doesn't exist, peco complains and exits
  2. $XDG_CONFIG_HOME/config.json
  3. $HOME/.config/peco/config.json
  4. for each directories listed in $XDG_CONFIG_DIRS, $DIR/peco/config.json
  5. If all else fails, $HOME/.peco/config.json

Below are configuration sections that you may specify in your config file:

Keymaps

Example:

{
    "Keymap": {
        "M-v": "peco.SelectPreviousPage",
        "C-v": "peco.SelectNextPage",
        "C-x,C-c": "peco.Cancel"
    }
}
Key sequences

As of v0.2.0, you can use a list of keys (separated by comma) to register an action that is associated with a key sequence (instead of a single key). Please note that if there is a conflict in the key map, the longest sequence always wins. So In the above example, if you add another sequence, say, C-x,C-c,C-c, then the above peco.Cancel will never be invoked.

Combined actions

As of v0.2.1, you can create custom combined actions. For example, if you find yourself repeatedly needing to select 4 lines out of the list, you may want to define your own action like this:

{
    "Action": {
        "foo.SelectFour": [
            "peco.ToggleRangeMode",
            "peco.SelectNext",
            "peco.SelectNext",
            "peco.SelectNext",
            "peco.ToggleRangeMode"
        ]
    },
    "Keymap": {
        "M-f": "foo.SelectFour"
    }
}

This creates a new combined action foo.SelectFour (the format of the name is totally arbitrary, I just like to put namespaces), and assigns that action to M-f. When it's fired, it toggles the range selection mode and highlights 4 lines, and then goes back to waiting for your input.

Available keys

Since v0.1.8, in addition to values below, you may put a M- prefix on any key item to use Alt/Option key as a mask.

Name Notes
C-a ... C-z Control + whatever character
C-1 ... C-8 Control + 1..8
C-[
C-]
C-~
C-_
C-\\ Note that you need to escape the backslash
C-/
Esc
Tab
Insert
Delete
Home
End
Pgup
Pgdn
ArrowUp
ArrowDown
ArrowLeft
ArrowRight
Key workarounds

Some keys just... don't map correctly / too easily for various reasons. Here, we'll list possible workarounds for key sequences that are often asked for:

You want this Use this instead Notes
Shift+Tab M-[,Z Verified on OS X
Available actions
Name Notes
peco.ForwardChar Move caret forward 1 character
peco.BackwardChar Move caret backward 1 character
peco.ForwardWord Move caret forward 1 word
peco.BackwardWord Move caret backward 1 word
peco.BeginningOfLine Move caret to the beginning of line
peco.EndOfLine Move caret to the end of line
peco.EndOfFile Delete one character forward, otherwise exit from peco with failure status
peco.DeleteForwardChar Delete one character forward
peco.DeleteBackwardChar Delete one character backward
peco.DeleteForwardWord Delete one word forward
peco.DeleteBackwardWord Delete one word backward
peco.KillEndOfLine Delete the characters under the cursor until the end of the line
peco.DeleteAll Delete all entered characters
peco.SelectPreviousPage Jumps to previous page
peco.SelectNextPage Jumps to next page
peco.SelectPrevious Selects previous line
peco.SelectNext Selects next line
peco.ToggleSelection Selects the current line, and saves it
peco.ToggleSelectionAndSelectNext Selects the current line, saves it, and proceeds to the next line
peco.ToggleRangeMode Start selecting by range, or append selecting range to selections
peco.CancelRangeMode Finish selecting by range and cancel range selection
peco.RotateMatcher Rotate between matchers (by default, ignore-case/no-ignore-case)
peco.Finish Exits from peco with success status
peco.Cancel Exits from peco with failure status, or cancel select mode
Default Keymap

Note: If in case below keymap seems wrong, check the source code in keymap.go (look for NewKeymap).

Key Action
Esc handleCancel
Ctrl-c handleCancel
Enter handleFinish
Ctrl-n handleSelectNext
Ctrl-p handleSelectPrevious
Ctrl-f handleForwardChar
Ctrl-b handleBackwardChar
Ctrl-a handleBeginningOfLine
Ctrl-e handleEndOfLine
Ctrl-d handleDeleteBackwardWord
Ctrl-w handleKillEndOfLine
Ctrl-u handleKillBeginOfLine
Ctrl-k handleKillEndOfLine
Ctrl-space handleToggleSelectionAndSelectNext
ArrorUp handleSelectPrevious
ArrowDown handleSelectNext
ArrowLeft handleSelectPreviousPage
ArrowRight handleSelectNextPage
Backspace handleDeleteBackwardChar
Ctrl-r handleRotateMatcher

Styles

For now, styles of following 5 items can be customized in config.json.

{
    "Style": {
        "Basic": ["on_default", "default"],
        "SavedSelection": ["bold", "on_yellow", "white"],
        "Selected": ["underline", "on_cyan", "black"],
        "Query": ["yellow", "bold"],
        "Matched": ["red", "on_blue"]
    }
}
  • Basic for not selected lines
  • SavedSelection for lines of saved selection
  • Selected for a currently selecting line
  • Query for a query line
  • Matched for a query matched word
Foreground Colors
  • "black" for termbox.ColorBlack
  • "red" for termbox.ColorRed
  • "green" for termbox.ColorGreen
  • "yellow" for termbox.ColorYellow
  • "blue" for termbox.ColorBlue
  • "magenta" for termbox.ColorMagenta
  • "cyan" for termbox.ColorCyan
  • "white" for termbox.ColorWhite
Background Colors
  • "on_black" for termbox.ColorBlack
  • "on_red" for termbox.ColorRed
  • "on_green" for termbox.ColorGreen
  • "on_yellow" for termbox.ColorYellow
  • "on_blue" for termbox.ColorBlue
  • "on_magenta" for termbox.ColorMagenta
  • "on_cyan" for termbox.ColorCyan
  • "on_white" for termbox.ColorWhite
Attributes
  • "bold" for termbox.AttrBold
  • "underline" for termbox.AttrUnderline
  • "blink" for termbox.AttrReverse

CustomMatcher

This is an experimental feature. Please note that some details of this specificaiton may change

By default peco comes with IgnoreCase, CaseSensitive, and Regexp matchers, but since v0.1.3, it is possible to create your own custom matcher.

The matcher will be executed via Command.Run() as an external process, and it will be passed the query values in the command line, and the original unaltered buffer is passed via os.Stdin. Your matcher must perform the matching, and print out to os.Stdout matched lines. Note that currently there is no way to specify where in the line the match occurred. Note that the matcher does not need to be a go program. It can be a perl/ruby/python/bash script, or anything else that is executable.

Once you have a matcher, you must specify how the matcher is spawned:

{
    "CustomMatcher": {
        "MyMatcher": [ "/path/to/my-matcher", "$QUERY" ]
    }
}

Elements in the CustomMatcher section are string keys to array of program arguments. The special token $QUERY will be replaced with the unaltered query as the user typed in (i.e. multiple-word queries will be passed as a single string). You may pass in any other arguments in this array.

You may specify as many matchers as you like.

Examples

Prompt

You can change the query line's prompt, which is QUERY> by default.

{
    "Prompt": "[peco]"
}

Hacking

First, fork this repo, and get your clone locally.

  1. Make sure you have go 1.x, with GOPATH appropriately set
  2. Run go get github.com/jessevdk/go-flags
  3. Run go get github.com/mattn/go-runewidth
  4. Run go get github.com/nsf/termbox-go

Note that we have a Godeps file in source tree, for now it's just there for a peace of mind. If you already know about godep, when you may use that instead of steps 2~4

In this repository, master branch is always the stable branch. master will only be merged from devel branch after the devel branch has been deemed stable enough to be merged to master

Then from the root of this repository run:

go build cmd/peco/peco.go

This will create a peco binary in the local directory.

TODO

Test it. In doing so, we may change the repo structure

Implement all(?) of the original percol options

AUTHORS

  • Daisuke Maki (lestrrat)
  • HIROSE Masaaki
  • Joel Segerlind
  • Lukas Lueg
  • Mitsuoka Mimura
  • Ryota Arai
  • Shinya Ohyanagi
  • syohex
  • Takashi Kokubun
  • Yuya Takeyama
  • cho45
  • cubicdaiya
  • kei_q
  • mattn
  • negipo
  • sugyan
  • swdyh
  • MURAOKA Taro (kaoriya/koron) for ahocorasick search

Notes

Obviously, kudos to the original percol: https://github.com/mooz/percol Much code stolen from https://github.com/mattn/gof

Documentation

Index

Constants

View Source
const (
	IgnoreCaseMatch    = "IgnoreCase"
	CaseSensitiveMatch = "CaseSensitive"
	RegexpMatch        = "Regexp"
)

These are used as keys in the config file

View Source
const NoSelectionRange = -1

Variables

This section is empty.

Functions

func IsTty

func IsTty(fd uintptr) bool

IsTty checks if the given fd is a tty

func LocateRcfile added in v0.1.3

func LocateRcfile() (string, error)

LocateRcfile attempts to find the config file in various locations

func TtyReady

func TtyReady() error

TtyReady checks if the tty is ready to go

func TtyTerm

func TtyTerm()

TtyTerm restores any state, if necessary

Types

type Action added in v0.2.0

type Action interface {
	Register(string, ...termbox.Key)
	RegisterKeySequence(keyseq.KeyList)
	Execute(*Input, termbox.Event)
}

Action describes an action that can be executed upon receiving user input. It's an interface so you can create any kind of Action you need, but most everything is implemented in terms of ActionFunc, which is callback based Action

type ActionFunc added in v0.2.0

type ActionFunc func(*Input, termbox.Event)

ActionFunc is a type of Action that is basically just a callback.

func (ActionFunc) Execute added in v0.2.0

func (a ActionFunc) Execute(i *Input, e termbox.Event)

Execute fulfills the Action interface for AfterFunc

func (ActionFunc) Register added in v0.2.0

func (a ActionFunc) Register(name string, defaultKeys ...termbox.Key)

Register fulfills the Actin interface for AfterFunc. Registers `a` into the global action registry by the name `name`, and maps to default keys via `defaultKeys`

func (ActionFunc) RegisterKeySequence added in v0.2.0

func (a ActionFunc) RegisterKeySequence(k keyseq.KeyList)

RegisterKeySequence satisfies the Action interface for AfterFun. Registers the action to be mapped against a key sequence

type BufferReader added in v0.1.12

type BufferReader struct {
	*Ctx
	// contains filtered or unexported fields
}

BufferReader reads lines from the input, either Stdin or a file. If the incoming data is endless, it keeps reading and adding to the search buffer, as long as it can.

If you would like to limit the number of lines to keep in the buffer, you should set --buffer-size to a number > 0

func (*BufferReader) InputReadyCh added in v0.2.0

func (b *BufferReader) InputReadyCh() <-chan struct{}

InputReadyCh returns a channel which, when the input starts coming in, sends a struct{}{}

func (*BufferReader) Loop added in v0.1.12

func (b *BufferReader) Loop()

Loop keeps reading from the input

type CaseSensitiveMatcher added in v0.1.1

type CaseSensitiveMatcher struct {
	*RegexpMatcher
}

CaseSensitiveMatcher extends the RegxpMatcher, but always turns off the ignore-case flag in the regexp

func NewCaseSensitiveMatcher added in v0.1.2

func NewCaseSensitiveMatcher(enableSep bool) *CaseSensitiveMatcher

NewCaseSensitiveMatcher creates a new CaseSensitiveMatcher

func (*CaseSensitiveMatcher) String added in v0.1.1

func (m *CaseSensitiveMatcher) String() string

type Config

type Config struct {
	Action map[string][]string `json:"Action"`
	// Keymap used to be directly responsible for dispatching
	// events against user input, but since then this has changed
	// into something that just records the user's config input
	Keymap        map[string]string `json:"Keymap"`
	Matcher       string            `json:"Matcher"`
	Style         StyleSet          `json:"Style"`
	CustomMatcher map[string][]string
	Prompt        string `json:"Prompt"`
}

Config holds all the data that can be configured in the external configuran file

func NewConfig

func NewConfig() *Config

NewConfig creates a new Config

func (*Config) ReadFilename

func (c *Config) ReadFilename(filename string) error

ReadFilename reads the config from the given file, and does the appropriate processing, if any

type Ctx

type Ctx struct {
	*Hub

	Matchers       []Matcher
	CurrentMatcher int
	ExitStatus     int
	// contains filtered or unexported fields
}

Ctx contains all the important data. while you can easily access data in this struct from anwyehre, only do so via channels

func NewCtx

func NewCtx(o CtxOptions) *Ctx

func (*Ctx) AddMatcher added in v0.1.2

func (c *Ctx) AddMatcher(m Matcher) error

func (*Ctx) AddWaitGroup

func (c *Ctx) AddWaitGroup(v int)

func (*Ctx) Buffer

func (c *Ctx) Buffer() []Match

func (*Ctx) DrawMatches

func (c *Ctx) DrawMatches(m []Match)

func (*Ctx) ExecQuery

func (c *Ctx) ExecQuery() bool

func (*Ctx) ExitWith added in v0.1.11

func (c *Ctx) ExitWith(i int)

func (*Ctx) IsBufferOverflowing added in v0.2.0

func (c *Ctx) IsBufferOverflowing() bool

func (*Ctx) IsRangeMode added in v0.2.0

func (c *Ctx) IsRangeMode() bool

func (*Ctx) LoadCustomMatcher added in v0.1.3

func (c *Ctx) LoadCustomMatcher() error

func (*Ctx) Matcher added in v0.1.1

func (c *Ctx) Matcher() Matcher

func (*Ctx) NewBufferReader added in v0.1.12

func (c *Ctx) NewBufferReader(r io.ReadCloser) *BufferReader

func (*Ctx) NewFilter

func (c *Ctx) NewFilter() *Filter

func (*Ctx) NewInput

func (c *Ctx) NewInput() *Input

func (*Ctx) NewSignalHandler added in v0.2.0

func (c *Ctx) NewSignalHandler() *SignalHandler

func (*Ctx) NewView

func (c *Ctx) NewView() *View

func (*Ctx) ReadConfig

func (c *Ctx) ReadConfig(file string) error

func (*Ctx) Refresh

func (c *Ctx) Refresh()

func (*Ctx) ReleaseWaitGroup

func (c *Ctx) ReleaseWaitGroup()

func (*Ctx) Result

func (c *Ctx) Result() []Match

func (*Ctx) SelectedRange added in v0.2.0

func (c *Ctx) SelectedRange() Selection

func (*Ctx) SetCurrentMatcher added in v0.1.2

func (c *Ctx) SetCurrentMatcher(n string) bool

func (*Ctx) SetPrompt added in v0.2.0

func (c *Ctx) SetPrompt(p []rune)

func (*Ctx) SetQuery

func (c *Ctx) SetQuery(q []rune)

func (*Ctx) WaitDone

func (c *Ctx) WaitDone()

type CtxOptions added in v0.2.0

type CtxOptions interface {
	EnableNullSep() bool
	BufferSize() int
	InitialIndex() int
}

type CustomMatcher added in v0.1.3

type CustomMatcher struct {
	// contains filtered or unexported fields
}

CustomMatcher spawns a new process to filter the buffer in peco, and uses the output in its Stdout to figure out what to display

func NewCustomMatcher added in v0.1.3

func NewCustomMatcher(enableSep bool, name string, args []string) *CustomMatcher

NewCustomMatcher creates a new CustomMatcher

func (*CustomMatcher) Match added in v0.1.3

func (m *CustomMatcher) Match(quit chan struct{}, q string, buffer []Match) []Match

Match matches `q` aginst `buffer`

func (*CustomMatcher) String added in v0.1.3

func (m *CustomMatcher) String() string

func (*CustomMatcher) Verify added in v0.1.11

func (m *CustomMatcher) Verify() error

Verify checks to see that the executable given to CustomMatcher is actual found and is executable via exec.LookPath

type DidMatch added in v0.1.3

type DidMatch struct {
	// contains filtered or unexported fields
}

DidMatch contains the actual match, and the indices to the matches in the line

func NewDidMatch added in v0.1.5

func NewDidMatch(v string, enableSep bool, m [][]int) *DidMatch

NewDidMatch creates a new DidMatch struct

func (DidMatch) Buffer added in v0.2.1

func (m DidMatch) Buffer() string

func (DidMatch) Indices added in v0.1.3

func (d DidMatch) Indices() [][]int

Indices returns the indices in the buffer that matched

func (DidMatch) Line added in v0.1.3

func (m DidMatch) Line() string

func (DidMatch) Output added in v0.2.1

func (m DidMatch) Output() string

type Filter

type Filter struct {
	*Ctx
	// contains filtered or unexported fields
}

Filter is responsible for the actual "grep" part of peco

func (*Filter) Loop

func (f *Filter) Loop()

Loop keeps watching for incoming queries, and upon receiving a query, spawns a goroutine to do the heavy work. It also checks for previously running queries, so we can avoid running many goroutines doing the grep at the same time

func (*Filter) Work added in v0.1.3

func (f *Filter) Work(cancel chan struct{}, q HubReq)

Work is the actual work horse that that does the matching in a goroutine of its own. It wraps Matcher.Match().

type Hub added in v0.2.1

type Hub struct {
	// contains filtered or unexported fields
}

Hub acts as the messaging hub between components -- that is, it controls how the communication that goes through channels are handled.

func NewHub added in v0.2.1

func NewHub() *Hub

NewHub creates a new Hub struct

func (*Hub) Batch added in v0.2.1

func (h *Hub) Batch(f func())

Batch allows you to synchronously send messages during the scope of f() being executed.

func (*Hub) ClearStatusCh added in v0.2.1

func (h *Hub) ClearStatusCh() chan HubReq

func (*Hub) DrawCh added in v0.2.1

func (h *Hub) DrawCh() chan HubReq

DrawCh returns the channel to redraw the terminal display

func (*Hub) LoopCh added in v0.2.1

func (h *Hub) LoopCh() chan struct{}

LoopCh returns the channel to control the main execution loop. Nothing should ever be sent through this channel. The only way the channel communicates anything to its receivers is when it is closed -- which is when peco is done.

func (*Hub) PagingCh added in v0.2.1

func (h *Hub) PagingCh() chan HubReq

PagingCh returns the channel to page through the results

func (*Hub) QueryCh added in v0.2.1

func (h *Hub) QueryCh() chan HubReq

QueryCh returns the underlying channel for queries

func (*Hub) SendClearStatus added in v0.2.1

func (h *Hub) SendClearStatus(d time.Duration)

SendClearStatus sends a request to clear the status message in `d` duration. If a new status message is sent before the clear request is executed, the clear instruction will be canceled

func (*Hub) SendDraw added in v0.2.1

func (h *Hub) SendDraw(matches []Match)

SendDraw sends a request to redraw the terminal display

func (*Hub) SendPaging added in v0.2.1

func (h *Hub) SendPaging(x PagingRequest)

SendPaging sends a request to move the cursor around

func (*Hub) SendQuery added in v0.2.1

func (h *Hub) SendQuery(q string)

SendQuery sends the query string to be processed by the Filter

func (*Hub) SendStatusMsg added in v0.2.1

func (h *Hub) SendStatusMsg(q string)

SendStatusMsg sends a string to be displayed in the status message

func (*Hub) StatusMsgCh added in v0.2.1

func (h *Hub) StatusMsgCh() chan HubReq

StatusMsgCh returns the channel to update the status message

func (*Hub) Stop added in v0.2.1

func (h *Hub) Stop()

Stop closes the LoopCh so that peco shutsdown

type HubReq added in v0.2.1

type HubReq struct {
	// contains filtered or unexported fields
}

HubReq is a wrapper around the actual requst value that needs to be passed. It contains an optional channel field which can be filled to force synchronous communication between the sender and receiver

func (HubReq) DataInterface added in v0.2.1

func (hr HubReq) DataInterface() interface{}

DataInterface returns the underlying data as interface{}

func (HubReq) DataString added in v0.2.1

func (hr HubReq) DataString() string

DataString returns the underlying data as a string. Panics if type conversion fails.

func (HubReq) Done added in v0.2.1

func (hr HubReq) Done()

Done marks the request as done. If Hub is operating in asynchronous mode (default), it's a no op. Otherwise it sends a message back the reply channel to finish up the synchronous communication

type IgnoreCaseMatcher added in v0.1.1

type IgnoreCaseMatcher struct {
	*RegexpMatcher
}

IgnoreCaseMatcher extends the RegexpMatcher, and always turns ON the ignore-case flag in the regexp

func NewIgnoreCaseMatcher added in v0.1.2

func NewIgnoreCaseMatcher(enableSep bool) *IgnoreCaseMatcher

NewIgnoreCaseMatcher creates a new IgnoreCaseMatcher

func (*IgnoreCaseMatcher) String added in v0.1.1

func (m *IgnoreCaseMatcher) String() string

type Input

type Input struct {
	*Ctx
	// contains filtered or unexported fields
}

Input handles input events from termbox.

func (*Input) Loop

func (i *Input) Loop()

Loop watches for incoming events from termbox, and pass them to the appropriate handler when something arrives.

type Keymap

type Keymap struct {
	Config map[string]string
	Action map[string][]string // custom actions
	Keyseq *keyseq.Keyseq
}

Keymap holds all the key sequence to action map

func NewKeymap

func NewKeymap(config map[string]string, actions map[string][]string) Keymap

NewKeymap creates a new Keymap struct

func (Keymap) ApplyKeybinding added in v0.2.0

func (km Keymap) ApplyKeybinding()

ApplyKeybinding applies all of the custom key bindings on top of the default key bindings

func (Keymap) Handler

func (km Keymap) Handler(ev termbox.Event) Action

Handler returns the appropriate action for the given termbox event

type Match

type Match interface {
	Buffer() string // Raw buffer, may contain null
	Line() string   // Line to be displayed
	Output() string // Output string to be displayed after peco is done
	Indices() [][]int
}

Match defines the interface for matches. Note that to make drawing easier, we have a DidMatch and NoMatch types instead of using []Match and []string.

type Matcher added in v0.1.1

type Matcher interface {
	// Match takes in three parameters.
	//
	// The first chan is the channel where cancel requests are sent.
	// If you receive a request here, you should stop running your query.
	//
	// The second is the query. Do what you want with it
	//
	// The third is the buffer in which to match the query against.
	Match(chan struct{}, string, []Match) []Match
	String() string

	// This is fugly. We just added a method only for CustomMatcner.
	// Must think about this again
	Verify() error
}

Matcher interface defines the API for things that want to match against the buffer

type NoMatch added in v0.1.3

type NoMatch struct {
	// contains filtered or unexported fields
}

NoMatch is actually an alias to a regular string. It implements the Match interface, but just returns the underlying string with no matches

func NewNoMatch added in v0.1.5

func NewNoMatch(v string, enableSep bool) *NoMatch

NewNoMatch creates a NoMatch struct

func (NoMatch) Buffer added in v0.2.1

func (m NoMatch) Buffer() string

func (NoMatch) Indices added in v0.1.3

func (m NoMatch) Indices() [][]int

Indices always returns nil

func (NoMatch) Line added in v0.1.3

func (m NoMatch) Line() string

func (NoMatch) Output added in v0.2.1

func (m NoMatch) Output() string

type PageInfo added in v0.2.1

type PageInfo struct {
	// contains filtered or unexported fields
}

type PagingRequest

type PagingRequest int

PagingRequest can be sent to move the selection cursor

const (
	// ToNextLine moves the selection to the next line
	ToNextLine PagingRequest = iota
	// ToNextPage moves the selection to the next page
	ToNextPage
	// ToPrevLine moves the selection to the previous line
	ToPrevLine
	// ToPrevPage moves the selection to the previous page
	ToPrevPage
)

type RegexpMatcher added in v0.1.2

type RegexpMatcher struct {
	// contains filtered or unexported fields
}

RegexpMatcher is the most basic matcher

func NewRegexpMatcher added in v0.1.2

func NewRegexpMatcher(enableSep bool) *RegexpMatcher

NewRegexpMatcher creates a new RegexpMatcher

func (*RegexpMatcher) Match added in v0.1.2

func (m *RegexpMatcher) Match(quit chan struct{}, q string, buffer []Match) []Match

Match does the heavy lifting, and matches `q` against `buffer`. While it is doing the match, it also listens for messages via `quit`. If anything is received via `quit`, the match is halted.

func (*RegexpMatcher) MatchAllRegexps added in v0.1.2

func (m *RegexpMatcher) MatchAllRegexps(regexps []*regexp.Regexp, line string) [][]int

MatchAllRegexps matches all the regexps in `regexps` against line

func (*RegexpMatcher) String added in v0.1.2

func (m *RegexpMatcher) String() string

func (*RegexpMatcher) Verify added in v0.1.11

func (m *RegexpMatcher) Verify() error

Verify always returns nil

type Selection added in v0.1.3

type Selection []int

Selection stores the line numbers that were selected by the user. The contents of the Selection is always sorted from smallest to largest line number

func (*Selection) Add added in v0.1.3

func (s *Selection) Add(v int)

Add adds a new line number to the selection. If the line already exists in the selection, it is silently ignored

func (*Selection) Clear added in v0.1.3

func (s *Selection) Clear()

Clear empties the selection

func (Selection) Has added in v0.1.3

func (s Selection) Has(v int) bool

Has returns true if line `v` is in the selection

func (Selection) Len added in v0.1.3

func (s Selection) Len() int

Len returns the number of elements in the selection. Satisfies sort.Interface

func (Selection) Less added in v0.1.3

func (s Selection) Less(i, j int) bool

Less returns true if element at index i is less than the element at index j. Satisfies sort.Interface

func (*Selection) Remove added in v0.1.3

func (s *Selection) Remove(v int)

Remove removes the specified line number from the selection

func (Selection) Swap added in v0.1.3

func (s Selection) Swap(i, j int)

Swap swaps the elements in indices i and j. Satisfies sort.Interface

type SignalHandler added in v0.2.0

type SignalHandler struct {
	*Ctx
	// contains filtered or unexported fields
}

func (*SignalHandler) Loop added in v0.2.0

func (s *SignalHandler) Loop()

type Style added in v0.1.2

type Style struct {
	// contains filtered or unexported fields
}

Style describes termbox styles

func (*Style) UnmarshalJSON added in v0.1.2

func (s *Style) UnmarshalJSON(buf []byte) error

UnmarshalJSON satisfies json.RawMessage.

type StyleSet added in v0.1.2

type StyleSet struct {
	Basic          Style `json:"Basic"`
	SavedSelection Style `json:"SavedSelection"`
	Selected       Style `json:"Selected"`
	Query          Style `json:"Query"`
	Matched        Style `json:"Matched"`
}

StyleSet holds styles for various sections

func NewStyleSet added in v0.1.2

func NewStyleSet() StyleSet

NewStyleSet creates a new StyleSet struct

type View

type View struct {
	*Ctx
	// contains filtered or unexported fields
}

View handles the drawing/updating the screen

func (*View) Loop

func (v *View) Loop()

Loop receives requests to update the screen

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL