mirror of
https://github.com/zyedidia/micro.git
synced 2026-02-06 23:20:18 +09:00
More actions and window organization
This commit is contained in:
@@ -9,450 +9,553 @@ import (
|
||||
|
||||
// MousePress is the event that should happen when a normal click happens
|
||||
// This is almost always bound to left click
|
||||
func (a *BufHandler) MousePress(e *tcell.EventMouse) bool {
|
||||
func (h *BufHandler) MousePress(e *tcell.EventMouse) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// ScrollUpAction scrolls the view up
|
||||
func (a *BufHandler) ScrollUpAction() bool {
|
||||
func (h *BufHandler) ScrollUpAction() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// ScrollDownAction scrolls the view up
|
||||
func (a *BufHandler) ScrollDownAction() bool {
|
||||
func (h *BufHandler) ScrollDownAction() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// Center centers the view on the cursor
|
||||
func (a *BufHandler) Center() bool {
|
||||
func (h *BufHandler) Center() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// CursorUp moves the cursor up
|
||||
func (a *BufHandler) CursorUp() bool {
|
||||
a.Cursor.Deselect(true)
|
||||
a.Cursor.Up()
|
||||
func (h *BufHandler) CursorUp() bool {
|
||||
h.Cursor.Deselect(true)
|
||||
h.Cursor.Up()
|
||||
return true
|
||||
}
|
||||
|
||||
// CursorDown moves the cursor down
|
||||
func (a *BufHandler) CursorDown() bool {
|
||||
a.Cursor.Deselect(true)
|
||||
a.Cursor.Down()
|
||||
func (h *BufHandler) CursorDown() bool {
|
||||
h.Cursor.Deselect(true)
|
||||
h.Cursor.Down()
|
||||
return true
|
||||
}
|
||||
|
||||
// CursorLeft moves the cursor left
|
||||
func (a *BufHandler) CursorLeft() bool {
|
||||
a.Cursor.Deselect(true)
|
||||
a.Cursor.Left()
|
||||
func (h *BufHandler) CursorLeft() bool {
|
||||
h.Cursor.Deselect(true)
|
||||
h.Cursor.Left()
|
||||
return true
|
||||
}
|
||||
|
||||
// CursorRight moves the cursor right
|
||||
func (a *BufHandler) CursorRight() bool {
|
||||
a.Cursor.Deselect(true)
|
||||
a.Cursor.Right()
|
||||
func (h *BufHandler) CursorRight() bool {
|
||||
h.Cursor.Deselect(true)
|
||||
h.Cursor.Right()
|
||||
return true
|
||||
}
|
||||
|
||||
// WordRight moves the cursor one word to the right
|
||||
func (a *BufHandler) WordRight() bool {
|
||||
func (h *BufHandler) WordRight() bool {
|
||||
h.Cursor.Deselect(true)
|
||||
h.Cursor.WordRight()
|
||||
return true
|
||||
}
|
||||
|
||||
// WordLeft moves the cursor one word to the left
|
||||
func (a *BufHandler) WordLeft() bool {
|
||||
func (h *BufHandler) WordLeft() bool {
|
||||
h.Cursor.Deselect(true)
|
||||
h.Cursor.WordLeft()
|
||||
return true
|
||||
}
|
||||
|
||||
// SelectUp selects up one line
|
||||
func (a *BufHandler) SelectUp() bool {
|
||||
func (h *BufHandler) SelectUp() bool {
|
||||
if !h.Cursor.HasSelection() {
|
||||
h.Cursor.OrigSelection[0] = h.Cursor.Loc
|
||||
}
|
||||
h.Cursor.Up()
|
||||
h.Cursor.SelectTo(h.Cursor.Loc)
|
||||
return true
|
||||
}
|
||||
|
||||
// SelectDown selects down one line
|
||||
func (a *BufHandler) SelectDown() bool {
|
||||
func (h *BufHandler) SelectDown() bool {
|
||||
if !h.Cursor.HasSelection() {
|
||||
h.Cursor.OrigSelection[0] = h.Cursor.Loc
|
||||
}
|
||||
h.Cursor.Down()
|
||||
h.Cursor.SelectTo(h.Cursor.Loc)
|
||||
return true
|
||||
}
|
||||
|
||||
// SelectLeft selects the character to the left of the cursor
|
||||
func (a *BufHandler) SelectLeft() bool {
|
||||
func (h *BufHandler) SelectLeft() bool {
|
||||
loc := h.Cursor.Loc
|
||||
count := h.Buf.End()
|
||||
if loc.GreaterThan(count) {
|
||||
loc = count
|
||||
}
|
||||
if !h.Cursor.HasSelection() {
|
||||
h.Cursor.OrigSelection[0] = loc
|
||||
}
|
||||
h.Cursor.Left()
|
||||
h.Cursor.SelectTo(h.Cursor.Loc)
|
||||
return true
|
||||
}
|
||||
|
||||
// SelectRight selects the character to the right of the cursor
|
||||
func (a *BufHandler) SelectRight() bool {
|
||||
func (h *BufHandler) SelectRight() bool {
|
||||
loc := h.Cursor.Loc
|
||||
count := h.Buf.End()
|
||||
if loc.GreaterThan(count) {
|
||||
loc = count
|
||||
}
|
||||
if !h.Cursor.HasSelection() {
|
||||
h.Cursor.OrigSelection[0] = loc
|
||||
}
|
||||
h.Cursor.Right()
|
||||
h.Cursor.SelectTo(h.Cursor.Loc)
|
||||
return true
|
||||
}
|
||||
|
||||
// SelectWordRight selects the word to the right of the cursor
|
||||
func (a *BufHandler) SelectWordRight() bool {
|
||||
func (h *BufHandler) SelectWordRight() bool {
|
||||
if !h.Cursor.HasSelection() {
|
||||
h.Cursor.OrigSelection[0] = h.Cursor.Loc
|
||||
}
|
||||
h.Cursor.WordRight()
|
||||
h.Cursor.SelectTo(h.Cursor.Loc)
|
||||
return true
|
||||
}
|
||||
|
||||
// SelectWordLeft selects the word to the left of the cursor
|
||||
func (a *BufHandler) SelectWordLeft() bool {
|
||||
func (h *BufHandler) SelectWordLeft() bool {
|
||||
if !h.Cursor.HasSelection() {
|
||||
h.Cursor.OrigSelection[0] = h.Cursor.Loc
|
||||
}
|
||||
h.Cursor.WordLeft()
|
||||
h.Cursor.SelectTo(h.Cursor.Loc)
|
||||
return true
|
||||
}
|
||||
|
||||
// StartOfLine moves the cursor to the start of the line
|
||||
func (a *BufHandler) StartOfLine() bool {
|
||||
func (h *BufHandler) StartOfLine() bool {
|
||||
h.Cursor.Deselect(true)
|
||||
if h.Cursor.X != 0 {
|
||||
h.Cursor.Start()
|
||||
} else {
|
||||
h.Cursor.StartOfText()
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// EndOfLine moves the cursor to the end of the line
|
||||
func (a *BufHandler) EndOfLine() bool {
|
||||
func (h *BufHandler) EndOfLine() bool {
|
||||
h.Cursor.Deselect(true)
|
||||
h.Cursor.End()
|
||||
return true
|
||||
}
|
||||
|
||||
// SelectLine selects the entire current line
|
||||
func (a *BufHandler) SelectLine() bool {
|
||||
func (h *BufHandler) SelectLine() bool {
|
||||
h.Cursor.SelectLine()
|
||||
return true
|
||||
}
|
||||
|
||||
// SelectToStartOfLine selects to the start of the current line
|
||||
func (a *BufHandler) SelectToStartOfLine() bool {
|
||||
func (h *BufHandler) SelectToStartOfLine() bool {
|
||||
if !h.Cursor.HasSelection() {
|
||||
h.Cursor.OrigSelection[0] = h.Cursor.Loc
|
||||
}
|
||||
h.Cursor.Start()
|
||||
h.Cursor.SelectTo(h.Cursor.Loc)
|
||||
return true
|
||||
}
|
||||
|
||||
// SelectToEndOfLine selects to the end of the current line
|
||||
func (a *BufHandler) SelectToEndOfLine() bool {
|
||||
func (h *BufHandler) SelectToEndOfLine() bool {
|
||||
if !h.Cursor.HasSelection() {
|
||||
h.Cursor.OrigSelection[0] = h.Cursor.Loc
|
||||
}
|
||||
h.Cursor.End()
|
||||
h.Cursor.SelectTo(h.Cursor.Loc)
|
||||
return true
|
||||
}
|
||||
|
||||
// ParagraphPrevious moves the cursor to the previous empty line, or beginning of the buffer if there's none
|
||||
func (a *BufHandler) ParagraphPrevious() bool {
|
||||
func (h *BufHandler) ParagraphPrevious() bool {
|
||||
var line int
|
||||
for line = h.Cursor.Y; line > 0; line-- {
|
||||
if len(h.Buf.LineBytes(line)) == 0 && line != h.Cursor.Y {
|
||||
h.Cursor.X = 0
|
||||
h.Cursor.Y = line
|
||||
break
|
||||
}
|
||||
}
|
||||
// If no empty line found. move cursor to end of buffer
|
||||
if line == 0 {
|
||||
h.Cursor.Loc = h.Buf.Start()
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// ParagraphNext moves the cursor to the next empty line, or end of the buffer if there's none
|
||||
func (a *BufHandler) ParagraphNext() bool {
|
||||
func (h *BufHandler) ParagraphNext() bool {
|
||||
var line int
|
||||
for line = h.Cursor.Y; line < h.Buf.LinesNum(); line++ {
|
||||
if len(h.Buf.LineBytes(line)) == 0 && line != h.Cursor.Y {
|
||||
h.Cursor.X = 0
|
||||
h.Cursor.Y = line
|
||||
break
|
||||
}
|
||||
}
|
||||
// If no empty line found. move cursor to end of buffer
|
||||
if line == h.Buf.LinesNum() {
|
||||
h.Cursor.Loc = h.Buf.End()
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Retab changes all tabs to spaces or all spaces to tabs depending
|
||||
// on the user's settings
|
||||
func (a *BufHandler) Retab() bool {
|
||||
func (h *BufHandler) Retab() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// CursorStart moves the cursor to the start of the buffer
|
||||
func (a *BufHandler) CursorStart() bool {
|
||||
func (h *BufHandler) CursorStart() bool {
|
||||
h.Cursor.Deselect(true)
|
||||
h.Cursor.X = 0
|
||||
h.Cursor.Y = 0
|
||||
return true
|
||||
}
|
||||
|
||||
// CursorEnd moves the cursor to the end of the buffer
|
||||
func (a *BufHandler) CursorEnd() bool {
|
||||
func (h *BufHandler) CursorEnd() bool {
|
||||
h.Cursor.Deselect(true)
|
||||
h.Cursor.Loc = h.Buf.End()
|
||||
h.Cursor.StoreVisualX()
|
||||
return true
|
||||
}
|
||||
|
||||
// SelectToStart selects the text from the cursor to the start of the buffer
|
||||
func (a *BufHandler) SelectToStart() bool {
|
||||
func (h *BufHandler) SelectToStart() bool {
|
||||
if !h.Cursor.HasSelection() {
|
||||
h.Cursor.OrigSelection[0] = h.Cursor.Loc
|
||||
}
|
||||
h.CursorStart()
|
||||
h.Cursor.SelectTo(h.Buf.Start())
|
||||
return true
|
||||
}
|
||||
|
||||
// SelectToEnd selects the text from the cursor to the end of the buffer
|
||||
func (a *BufHandler) SelectToEnd() bool {
|
||||
func (h *BufHandler) SelectToEnd() bool {
|
||||
if !h.Cursor.HasSelection() {
|
||||
h.Cursor.OrigSelection[0] = h.Cursor.Loc
|
||||
}
|
||||
h.CursorEnd()
|
||||
h.Cursor.SelectTo(h.Buf.End())
|
||||
return true
|
||||
}
|
||||
|
||||
// InsertSpace inserts a space
|
||||
func (a *BufHandler) InsertSpace() bool {
|
||||
func (h *BufHandler) InsertSpace() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// InsertNewline inserts a newline plus possible some whitespace if autoindent is on
|
||||
func (a *BufHandler) InsertNewline() bool {
|
||||
func (h *BufHandler) InsertNewline() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// Backspace deletes the previous character
|
||||
func (a *BufHandler) Backspace() bool {
|
||||
func (h *BufHandler) Backspace() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// DeleteWordRight deletes the word to the right of the cursor
|
||||
func (a *BufHandler) DeleteWordRight() bool {
|
||||
func (h *BufHandler) DeleteWordRight() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// DeleteWordLeft deletes the word to the left of the cursor
|
||||
func (a *BufHandler) DeleteWordLeft() bool {
|
||||
func (h *BufHandler) DeleteWordLeft() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// Delete deletes the next character
|
||||
func (a *BufHandler) Delete() bool {
|
||||
func (h *BufHandler) Delete() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// IndentSelection indents the current selection
|
||||
func (a *BufHandler) IndentSelection() bool {
|
||||
func (h *BufHandler) IndentSelection() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// OutdentLine moves the current line back one indentation
|
||||
func (a *BufHandler) OutdentLine() bool {
|
||||
func (h *BufHandler) OutdentLine() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// OutdentSelection takes the current selection and moves it back one indent level
|
||||
func (a *BufHandler) OutdentSelection() bool {
|
||||
func (h *BufHandler) OutdentSelection() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// InsertTab inserts a tab or spaces
|
||||
func (a *BufHandler) InsertTab() bool {
|
||||
func (h *BufHandler) InsertTab() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// SaveAll saves all open buffers
|
||||
func (a *BufHandler) SaveAll() bool {
|
||||
func (h *BufHandler) SaveAll() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// Save the buffer to disk
|
||||
func (a *BufHandler) Save() bool {
|
||||
func (h *BufHandler) Save() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// SaveAs saves the buffer to disk with the given name
|
||||
func (a *BufHandler) SaveAs() bool {
|
||||
func (h *BufHandler) SaveAs() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// Find opens a prompt and searches forward for the input
|
||||
func (a *BufHandler) Find() bool {
|
||||
func (h *BufHandler) Find() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// FindNext searches forwards for the last used search term
|
||||
func (a *BufHandler) FindNext() bool {
|
||||
func (h *BufHandler) FindNext() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// FindPrevious searches backwards for the last used search term
|
||||
func (a *BufHandler) FindPrevious() bool {
|
||||
func (h *BufHandler) FindPrevious() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// Undo undoes the last action
|
||||
func (a *BufHandler) Undo() bool {
|
||||
func (h *BufHandler) Undo() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// Redo redoes the last action
|
||||
func (a *BufHandler) Redo() bool {
|
||||
func (h *BufHandler) Redo() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// Copy the selection to the system clipboard
|
||||
func (a *BufHandler) Copy() bool {
|
||||
func (h *BufHandler) Copy() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// CutLine cuts the current line to the clipboard
|
||||
func (a *BufHandler) CutLine() bool {
|
||||
func (h *BufHandler) CutLine() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// Cut the selection to the system clipboard
|
||||
func (a *BufHandler) Cut() bool {
|
||||
func (h *BufHandler) Cut() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// DuplicateLine duplicates the current line or selection
|
||||
func (a *BufHandler) DuplicateLine() bool {
|
||||
func (h *BufHandler) DuplicateLine() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// DeleteLine deletes the current line
|
||||
func (a *BufHandler) DeleteLine() bool {
|
||||
func (h *BufHandler) DeleteLine() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// MoveLinesUp moves up the current line or selected lines if any
|
||||
func (a *BufHandler) MoveLinesUp() bool {
|
||||
func (h *BufHandler) MoveLinesUp() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// MoveLinesDown moves down the current line or selected lines if any
|
||||
func (a *BufHandler) MoveLinesDown() bool {
|
||||
func (h *BufHandler) MoveLinesDown() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// Paste whatever is in the system clipboard into the buffer
|
||||
// Delete and paste if the user has a selection
|
||||
func (a *BufHandler) Paste() bool {
|
||||
func (h *BufHandler) Paste() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// PastePrimary pastes from the primary clipboard (only use on linux)
|
||||
func (a *BufHandler) PastePrimary() bool {
|
||||
func (h *BufHandler) PastePrimary() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// JumpToMatchingBrace moves the cursor to the matching brace if it is
|
||||
// currently on a brace
|
||||
func (a *BufHandler) JumpToMatchingBrace() bool {
|
||||
func (h *BufHandler) JumpToMatchingBrace() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// SelectAll selects the entire buffer
|
||||
func (a *BufHandler) SelectAll() bool {
|
||||
func (h *BufHandler) SelectAll() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// OpenFile opens a new file in the buffer
|
||||
func (a *BufHandler) OpenFile() bool {
|
||||
func (h *BufHandler) OpenFile() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// Start moves the viewport to the start of the buffer
|
||||
func (a *BufHandler) Start() bool {
|
||||
func (h *BufHandler) Start() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// End moves the viewport to the end of the buffer
|
||||
func (a *BufHandler) End() bool {
|
||||
func (h *BufHandler) End() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// PageUp scrolls the view up a page
|
||||
func (a *BufHandler) PageUp() bool {
|
||||
func (h *BufHandler) PageUp() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// PageDown scrolls the view down a page
|
||||
func (a *BufHandler) PageDown() bool {
|
||||
func (h *BufHandler) PageDown() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// SelectPageUp selects up one page
|
||||
func (a *BufHandler) SelectPageUp() bool {
|
||||
func (h *BufHandler) SelectPageUp() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// SelectPageDown selects down one page
|
||||
func (a *BufHandler) SelectPageDown() bool {
|
||||
func (h *BufHandler) SelectPageDown() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// CursorPageUp places the cursor a page up
|
||||
func (a *BufHandler) CursorPageUp() bool {
|
||||
func (h *BufHandler) CursorPageUp() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// CursorPageDown places the cursor a page up
|
||||
func (a *BufHandler) CursorPageDown() bool {
|
||||
func (h *BufHandler) CursorPageDown() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// HalfPageUp scrolls the view up half a page
|
||||
func (a *BufHandler) HalfPageUp() bool {
|
||||
func (h *BufHandler) HalfPageUp() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// HalfPageDown scrolls the view down half a page
|
||||
func (a *BufHandler) HalfPageDown() bool {
|
||||
func (h *BufHandler) HalfPageDown() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// ToggleRuler turns line numbers off and on
|
||||
func (a *BufHandler) ToggleRuler() bool {
|
||||
func (h *BufHandler) ToggleRuler() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// JumpLine jumps to a line and moves the view accordingly.
|
||||
func (a *BufHandler) JumpLine() bool {
|
||||
func (h *BufHandler) JumpLine() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// ClearStatus clears the messenger bar
|
||||
func (a *BufHandler) ClearStatus() bool {
|
||||
func (h *BufHandler) ClearStatus() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// ToggleHelp toggles the help screen
|
||||
func (a *BufHandler) ToggleHelp() bool {
|
||||
func (h *BufHandler) ToggleHelp() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// ToggleKeyMenu toggles the keymenu option and resizes all tabs
|
||||
func (a *BufHandler) ToggleKeyMenu() bool {
|
||||
func (h *BufHandler) ToggleKeyMenu() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// ShellMode opens a terminal to run a shell command
|
||||
func (a *BufHandler) ShellMode() bool {
|
||||
func (h *BufHandler) ShellMode() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// CommandMode lets the user enter a command
|
||||
func (a *BufHandler) CommandMode() bool {
|
||||
func (h *BufHandler) CommandMode() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// ToggleOverwriteMode lets the user toggle the text overwrite mode
|
||||
func (a *BufHandler) ToggleOverwriteMode() bool {
|
||||
func (h *BufHandler) ToggleOverwriteMode() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// Escape leaves current mode
|
||||
func (a *BufHandler) Escape() bool {
|
||||
func (h *BufHandler) Escape() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// Quit this will close the current tab or view that is open
|
||||
func (a *BufHandler) Quit() bool {
|
||||
func (h *BufHandler) Quit() bool {
|
||||
screen.Screen.Fini()
|
||||
os.Exit(0)
|
||||
return false
|
||||
}
|
||||
|
||||
// QuitAll quits the whole editor; all splits and tabs
|
||||
func (a *BufHandler) QuitAll() bool {
|
||||
func (h *BufHandler) QuitAll() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// AddTab adds a new tab with an empty buffer
|
||||
func (a *BufHandler) AddTab() bool {
|
||||
func (h *BufHandler) AddTab() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// PreviousTab switches to the previous tab in the tab list
|
||||
func (a *BufHandler) PreviousTab() bool {
|
||||
func (h *BufHandler) PreviousTab() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// NextTab switches to the next tab in the tab list
|
||||
func (a *BufHandler) NextTab() bool {
|
||||
func (h *BufHandler) NextTab() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// VSplitBinding opens an empty vertical split
|
||||
func (a *BufHandler) VSplitBinding() bool {
|
||||
func (h *BufHandler) VSplitBinding() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// HSplitBinding opens an empty horizontal split
|
||||
func (a *BufHandler) HSplitBinding() bool {
|
||||
func (h *BufHandler) HSplitBinding() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// Unsplit closes all splits in the current tab except the active one
|
||||
func (a *BufHandler) Unsplit() bool {
|
||||
func (h *BufHandler) Unsplit() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// NextSplit changes the view to the next split
|
||||
func (a *BufHandler) NextSplit() bool {
|
||||
func (h *BufHandler) NextSplit() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// PreviousSplit changes the view to the previous split
|
||||
func (a *BufHandler) PreviousSplit() bool {
|
||||
func (h *BufHandler) PreviousSplit() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -460,41 +563,41 @@ var curMacro []interface{}
|
||||
var recordingMacro bool
|
||||
|
||||
// ToggleMacro toggles recording of a macro
|
||||
func (a *BufHandler) ToggleMacro() bool {
|
||||
func (h *BufHandler) ToggleMacro() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// PlayMacro plays back the most recently recorded macro
|
||||
func (a *BufHandler) PlayMacro() bool {
|
||||
func (h *BufHandler) PlayMacro() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// SpawnMultiCursor creates a new multiple cursor at the next occurrence of the current selection or current word
|
||||
func (a *BufHandler) SpawnMultiCursor() bool {
|
||||
func (h *BufHandler) SpawnMultiCursor() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// SpawnMultiCursorSelect adds a cursor at the beginning of each line of a selection
|
||||
func (a *BufHandler) SpawnMultiCursorSelect() bool {
|
||||
func (h *BufHandler) SpawnMultiCursorSelect() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// MouseMultiCursor is a mouse action which puts a new cursor at the mouse position
|
||||
func (a *BufHandler) MouseMultiCursor(e *tcell.EventMouse) bool {
|
||||
func (h *BufHandler) MouseMultiCursor(e *tcell.EventMouse) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// SkipMultiCursor moves the current multiple cursor to the next available position
|
||||
func (a *BufHandler) SkipMultiCursor() bool {
|
||||
func (h *BufHandler) SkipMultiCursor() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// RemoveMultiCursor removes the latest multiple cursor
|
||||
func (a *BufHandler) RemoveMultiCursor() bool {
|
||||
func (h *BufHandler) RemoveMultiCursor() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// RemoveAllMultiCursors removes all cursors except the base cursor
|
||||
func (a *BufHandler) RemoveAllMultiCursors() bool {
|
||||
func (h *BufHandler) RemoveAllMultiCursors() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -36,6 +36,9 @@ type BufHandler struct {
|
||||
cursors []*buffer.Cursor
|
||||
Cursor *buffer.Cursor // the active cursor
|
||||
|
||||
StartLine int // Vertical scrolling
|
||||
StartCol int // Horizontal scrolling
|
||||
|
||||
// Since tcell doesn't differentiate between a mouse release event
|
||||
// and a mouse move event with no keys pressed, we need to keep
|
||||
// track of whether or not the mouse was pressed (or not released) last event to determine
|
||||
@@ -65,22 +68,22 @@ type BufHandler struct {
|
||||
}
|
||||
|
||||
func NewBufHandler(buf *buffer.Buffer) *BufHandler {
|
||||
a := new(BufHandler)
|
||||
a.Buf = buf
|
||||
h := new(BufHandler)
|
||||
h.Buf = buf
|
||||
|
||||
a.cursors = []*buffer.Cursor{&buffer.Cursor{
|
||||
h.cursors = []*buffer.Cursor{&buffer.Cursor{
|
||||
Buf: buf,
|
||||
Loc: buf.StartCursor,
|
||||
}}
|
||||
a.Cursor = a.cursors[0]
|
||||
h.Cursor = h.cursors[0]
|
||||
|
||||
buf.SetCursors(a.cursors)
|
||||
return a
|
||||
buf.SetCursors(h.cursors)
|
||||
return h
|
||||
}
|
||||
|
||||
// HandleEvent executes the tcell event properly
|
||||
// TODO: multiple actions bound to one key
|
||||
func (a *BufHandler) HandleEvent(event tcell.Event) {
|
||||
func (h *BufHandler) HandleEvent(event tcell.Event) {
|
||||
switch e := event.(type) {
|
||||
case *tcell.EventKey:
|
||||
ke := KeyEvent{
|
||||
@@ -88,20 +91,32 @@ func (a *BufHandler) HandleEvent(event tcell.Event) {
|
||||
mod: e.Modifiers(),
|
||||
r: e.Rune(),
|
||||
}
|
||||
if action, ok := BufKeyBindings[ke]; ok {
|
||||
action(a)
|
||||
}
|
||||
h.DoKeyEvent(ke)
|
||||
case *tcell.EventMouse:
|
||||
me := MouseEvent{
|
||||
btn: e.Buttons(),
|
||||
mod: e.Modifiers(),
|
||||
}
|
||||
if action, ok := BufMouseBindings[me]; ok {
|
||||
action(a, e)
|
||||
}
|
||||
h.DoMouseEvent(me, e)
|
||||
}
|
||||
}
|
||||
|
||||
func (h *BufHandler) DoKeyEvent(e KeyEvent) bool {
|
||||
if action, ok := BufKeyBindings[e]; ok {
|
||||
action(h)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (h *BufHandler) DoMouseEvent(e MouseEvent, te *tcell.EventMouse) bool {
|
||||
if action, ok := BufMouseBindings[e]; ok {
|
||||
action(h, te)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
var BufKeyActions = map[string]BufKeyAction{
|
||||
"CursorUp": (*BufHandler).CursorUp,
|
||||
"CursorDown": (*BufHandler).CursorDown,
|
||||
|
||||
@@ -31,8 +31,13 @@ type MouseEvent struct {
|
||||
mod tcell.ModMask
|
||||
}
|
||||
|
||||
type KeyAction func(Handler) bool
|
||||
type MouseAction func(Handler, tcell.EventMouse) bool
|
||||
|
||||
// A Handler will take a tcell event and execute it
|
||||
// appropriately
|
||||
type Handler interface {
|
||||
// DoKeyEvent(KeyEvent) bool
|
||||
// DoMouseEvent(MouseEvent, *tcell.EventMouse) (MouseAction, bool)
|
||||
HandleEvent(tcell.Event)
|
||||
}
|
||||
|
||||
@@ -107,6 +107,18 @@ func (c *Cursor) Start() {
|
||||
c.LastVisualX = c.GetVisualX()
|
||||
}
|
||||
|
||||
// StartOfText moves the cursor to the first non-whitespace rune of
|
||||
// the line it is on
|
||||
func (c *Cursor) StartOfText() {
|
||||
c.Start()
|
||||
for util.IsWhitespace(c.RuneUnder(c.X)) {
|
||||
if c.X == utf8.RuneCount(c.Buf.LineBytes(c.Y)) {
|
||||
break
|
||||
}
|
||||
c.Right()
|
||||
}
|
||||
}
|
||||
|
||||
// End moves the cursor to the end of the line it is on
|
||||
func (c *Cursor) End() {
|
||||
c.X = utf8.RuneCount(c.Buf.LineBytes(c.Y))
|
||||
@@ -296,6 +308,143 @@ func (c *Cursor) Relocate() {
|
||||
}
|
||||
}
|
||||
|
||||
// SelectWord selects the word the cursor is currently on
|
||||
func (c *Cursor) SelectWord() {
|
||||
if len(c.Buf.LineBytes(c.Y)) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
if !util.IsWordChar(c.RuneUnder(c.X)) {
|
||||
c.SetSelectionStart(c.Loc)
|
||||
c.SetSelectionEnd(c.Loc.Move(1, c.Buf))
|
||||
c.OrigSelection = c.CurSelection
|
||||
return
|
||||
}
|
||||
|
||||
forward, backward := c.X, c.X
|
||||
|
||||
for backward > 0 && util.IsWordChar(c.RuneUnder(backward-1)) {
|
||||
backward--
|
||||
}
|
||||
|
||||
c.SetSelectionStart(Loc{backward, c.Y})
|
||||
c.OrigSelection[0] = c.CurSelection[0]
|
||||
|
||||
lineLen := utf8.RuneCount(c.Buf.LineBytes(c.Y)) - 1
|
||||
for forward < lineLen && util.IsWordChar(c.RuneUnder(forward+1)) {
|
||||
forward++
|
||||
}
|
||||
|
||||
c.SetSelectionEnd(Loc{forward, c.Y}.Move(1, c.Buf))
|
||||
c.OrigSelection[1] = c.CurSelection[1]
|
||||
c.Loc = c.CurSelection[1]
|
||||
}
|
||||
|
||||
// AddWordToSelection adds the word the cursor is currently on
|
||||
// to the selection
|
||||
func (c *Cursor) AddWordToSelection() {
|
||||
if c.Loc.GreaterThan(c.OrigSelection[0]) && c.Loc.LessThan(c.OrigSelection[1]) {
|
||||
c.CurSelection = c.OrigSelection
|
||||
return
|
||||
}
|
||||
|
||||
if c.Loc.LessThan(c.OrigSelection[0]) {
|
||||
backward := c.X
|
||||
|
||||
for backward > 0 && util.IsWordChar(c.RuneUnder(backward-1)) {
|
||||
backward--
|
||||
}
|
||||
|
||||
c.SetSelectionStart(Loc{backward, c.Y})
|
||||
c.SetSelectionEnd(c.OrigSelection[1])
|
||||
}
|
||||
|
||||
if c.Loc.GreaterThan(c.OrigSelection[1]) {
|
||||
forward := c.X
|
||||
|
||||
lineLen := utf8.RuneCount(c.Buf.LineBytes(c.Y)) - 1
|
||||
for forward < lineLen && util.IsWordChar(c.RuneUnder(forward+1)) {
|
||||
forward++
|
||||
}
|
||||
|
||||
c.SetSelectionEnd(Loc{forward, c.Y}.Move(1, c.Buf))
|
||||
c.SetSelectionStart(c.OrigSelection[0])
|
||||
}
|
||||
|
||||
c.Loc = c.CurSelection[1]
|
||||
}
|
||||
|
||||
// SelectTo selects from the current cursor location to the given
|
||||
// location
|
||||
func (c *Cursor) SelectTo(loc Loc) {
|
||||
if loc.GreaterThan(c.OrigSelection[0]) {
|
||||
c.SetSelectionStart(c.OrigSelection[0])
|
||||
c.SetSelectionEnd(loc)
|
||||
} else {
|
||||
c.SetSelectionStart(loc)
|
||||
c.SetSelectionEnd(c.OrigSelection[0])
|
||||
}
|
||||
}
|
||||
|
||||
// WordRight moves the cursor one word to the right
|
||||
func (c *Cursor) WordRight() {
|
||||
for util.IsWhitespace(c.RuneUnder(c.X)) {
|
||||
if c.X == utf8.RuneCount(c.Buf.LineBytes(c.Y)) {
|
||||
c.Right()
|
||||
return
|
||||
}
|
||||
c.Right()
|
||||
}
|
||||
c.Right()
|
||||
for util.IsWordChar(c.RuneUnder(c.X)) {
|
||||
if c.X == utf8.RuneCount(c.Buf.LineBytes(c.Y)) {
|
||||
return
|
||||
}
|
||||
c.Right()
|
||||
}
|
||||
}
|
||||
|
||||
// WordLeft moves the cursor one word to the left
|
||||
func (c *Cursor) WordLeft() {
|
||||
c.Left()
|
||||
for util.IsWhitespace(c.RuneUnder(c.X)) {
|
||||
if c.X == 0 {
|
||||
return
|
||||
}
|
||||
c.Left()
|
||||
}
|
||||
c.Left()
|
||||
for util.IsWordChar(c.RuneUnder(c.X)) {
|
||||
if c.X == 0 {
|
||||
return
|
||||
}
|
||||
c.Left()
|
||||
}
|
||||
c.Right()
|
||||
}
|
||||
|
||||
// RuneUnder returns the rune under the given x position
|
||||
func (c *Cursor) RuneUnder(x int) rune {
|
||||
line := c.Buf.LineBytes(c.Y)
|
||||
if len(line) == 0 || x >= utf8.RuneCount(line) {
|
||||
return '\n'
|
||||
} else if x < 0 {
|
||||
x = 0
|
||||
}
|
||||
i := 0
|
||||
for len(line) > 0 {
|
||||
r, size := utf8.DecodeRune(line)
|
||||
line = line[size:]
|
||||
|
||||
if i == x {
|
||||
return r
|
||||
}
|
||||
|
||||
i++
|
||||
}
|
||||
return '\n'
|
||||
}
|
||||
|
||||
func (c *Cursor) StoreVisualX() {
|
||||
c.LastVisualX = c.GetVisualX()
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package main
|
||||
package display
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -1,4 +1,4 @@
|
||||
package main
|
||||
package display
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
@@ -23,13 +23,13 @@ type StatusLine struct {
|
||||
FormatRight string
|
||||
Info map[string]func(*buffer.Buffer) string
|
||||
|
||||
win *Window
|
||||
win *BufWindow
|
||||
}
|
||||
|
||||
// TODO: plugin modify status line formatter
|
||||
|
||||
// NewStatusLine returns a statusline bound to a window
|
||||
func NewStatusLine(win *Window) *StatusLine {
|
||||
func NewStatusLine(win *BufWindow) *StatusLine {
|
||||
s := new(StatusLine)
|
||||
s.FormatLeft = "$(filename) $(modified)($(line),$(col)) $(opt:filetype) $(opt:fileformat)"
|
||||
// s.FormatLeft = "$(filename) $(modified)(line,col) $(opt:filetype) $(opt:fileformat)"
|
||||
@@ -1,4 +1,4 @@
|
||||
package main
|
||||
package display
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
@@ -12,7 +12,12 @@ import (
|
||||
"github.com/zyedidia/tcell"
|
||||
)
|
||||
|
||||
type Window struct {
|
||||
type Window interface {
|
||||
Display()
|
||||
Clear()
|
||||
}
|
||||
|
||||
type BufWindow struct {
|
||||
// X and Y coordinates for the top left of the window
|
||||
X int
|
||||
Y int
|
||||
@@ -32,8 +37,8 @@ type Window struct {
|
||||
sline *StatusLine
|
||||
}
|
||||
|
||||
func NewWindow(x, y, width, height int, buf *buffer.Buffer) *Window {
|
||||
w := new(Window)
|
||||
func NewBufWindow(x, y, width, height int, buf *buffer.Buffer) *BufWindow {
|
||||
w := new(BufWindow)
|
||||
w.X, w.Y, w.Width, w.Height, w.Buf = x, y, width, height, buf
|
||||
|
||||
w.sline = NewStatusLine(w)
|
||||
@@ -41,7 +46,7 @@ func NewWindow(x, y, width, height int, buf *buffer.Buffer) *Window {
|
||||
return w
|
||||
}
|
||||
|
||||
func (w *Window) Clear() {
|
||||
func (w *BufWindow) Clear() {
|
||||
for y := 0; y < w.Height; y++ {
|
||||
for x := 0; x < w.Width; x++ {
|
||||
screen.Screen.SetContent(w.X+x, w.Y+y, ' ', nil, config.DefStyle)
|
||||
@@ -49,7 +54,7 @@ func (w *Window) Clear() {
|
||||
}
|
||||
}
|
||||
|
||||
func (w *Window) DrawLineNum(lineNumStyle tcell.Style, softwrapped bool, maxLineNumLength int, vloc *buffer.Loc, bloc *buffer.Loc) {
|
||||
func (w *BufWindow) drawLineNum(lineNumStyle tcell.Style, softwrapped bool, maxLineNumLength int, vloc *buffer.Loc, bloc *buffer.Loc) {
|
||||
lineNum := strconv.Itoa(bloc.Y + 1)
|
||||
|
||||
// Write the spaces before the line number if necessary
|
||||
@@ -72,9 +77,9 @@ func (w *Window) DrawLineNum(lineNumStyle tcell.Style, softwrapped bool, maxLine
|
||||
vloc.X++
|
||||
}
|
||||
|
||||
// GetStyle returns the highlight style for the given character position
|
||||
// getStyle returns the highlight style for the given character position
|
||||
// If there is no change to the current highlight style it just returns that
|
||||
func (w *Window) GetStyle(style tcell.Style, bloc buffer.Loc, r rune) tcell.Style {
|
||||
func (w *BufWindow) getStyle(style tcell.Style, bloc buffer.Loc, r rune) tcell.Style {
|
||||
if group, ok := w.Buf.Match(bloc.Y)[bloc.X]; ok {
|
||||
s := config.GetColor(group.String())
|
||||
return s
|
||||
@@ -82,7 +87,7 @@ func (w *Window) GetStyle(style tcell.Style, bloc buffer.Loc, r rune) tcell.Styl
|
||||
return style
|
||||
}
|
||||
|
||||
func (w *Window) ShowCursor(x, y int, main bool) {
|
||||
func (w *BufWindow) showCursor(x, y int, main bool) {
|
||||
if main {
|
||||
screen.Screen.ShowCursor(x, y)
|
||||
} else {
|
||||
@@ -91,8 +96,8 @@ func (w *Window) ShowCursor(x, y int, main bool) {
|
||||
}
|
||||
}
|
||||
|
||||
// DisplayBuffer draws the buffer being shown in this window on the screen.Screen
|
||||
func (w *Window) DisplayBuffer() {
|
||||
// displayBuffer draws the buffer being shown in this window on the screen.Screen
|
||||
func (w *BufWindow) displayBuffer() {
|
||||
b := w.Buf
|
||||
|
||||
bufHeight := w.Height
|
||||
@@ -132,30 +137,48 @@ func (w *Window) DisplayBuffer() {
|
||||
// this represents the current draw position in the buffer (char positions)
|
||||
bloc := buffer.Loc{w.StartCol, w.StartLine}
|
||||
|
||||
activeC := w.Buf.GetActiveCursor()
|
||||
|
||||
curStyle := config.DefStyle
|
||||
for vloc.Y = 0; vloc.Y < bufHeight; vloc.Y++ {
|
||||
vloc.X = 0
|
||||
if b.Settings["ruler"].(bool) {
|
||||
w.DrawLineNum(lineNumStyle, false, maxLineNumLength, &vloc, &bloc)
|
||||
w.drawLineNum(lineNumStyle, false, maxLineNumLength, &vloc, &bloc)
|
||||
}
|
||||
|
||||
line := b.LineBytes(bloc.Y)
|
||||
line, nColsBeforeStart := util.SliceVisualEnd(line, bloc.X, tabsize)
|
||||
totalwidth := bloc.X - nColsBeforeStart
|
||||
for len(line) > 0 {
|
||||
if w.Buf.GetActiveCursor().X == bloc.X && w.Buf.GetActiveCursor().Y == bloc.Y {
|
||||
w.ShowCursor(vloc.X, vloc.Y, true)
|
||||
}
|
||||
|
||||
r, size := utf8.DecodeRune(line)
|
||||
|
||||
curStyle = w.GetStyle(curStyle, bloc, r)
|
||||
|
||||
draw := func(r rune, style tcell.Style) {
|
||||
if nColsBeforeStart <= 0 {
|
||||
screen.Screen.SetContent(w.X+vloc.X, w.Y+vloc.Y, r, nil, curStyle)
|
||||
if activeC.HasSelection() &&
|
||||
(bloc.GreaterEqual(activeC.CurSelection[0]) && bloc.LessThan(activeC.CurSelection[1]) ||
|
||||
bloc.LessThan(activeC.CurSelection[0]) && bloc.GreaterEqual(activeC.CurSelection[1])) {
|
||||
// The current character is selected
|
||||
style = config.DefStyle.Reverse(true)
|
||||
|
||||
if s, ok := config.Colorscheme["selection"]; ok {
|
||||
style = s
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
screen.Screen.SetContent(w.X+vloc.X, w.Y+vloc.Y, r, nil, style)
|
||||
vloc.X++
|
||||
}
|
||||
nColsBeforeStart--
|
||||
}
|
||||
|
||||
totalwidth := bloc.X - nColsBeforeStart
|
||||
for len(line) > 0 {
|
||||
if activeC.X == bloc.X && activeC.Y == bloc.Y {
|
||||
w.showCursor(vloc.X, vloc.Y, true)
|
||||
}
|
||||
|
||||
r, size := utf8.DecodeRune(line)
|
||||
curStyle = w.getStyle(curStyle, bloc, r)
|
||||
|
||||
draw(r, curStyle)
|
||||
|
||||
width := 0
|
||||
|
||||
@@ -175,11 +198,7 @@ func (w *Window) DisplayBuffer() {
|
||||
// Draw any extra characters either spaces for tabs or @ for incomplete wide runes
|
||||
if width > 1 {
|
||||
for i := 1; i < width; i++ {
|
||||
if nColsBeforeStart <= 0 {
|
||||
screen.Screen.SetContent(w.X+vloc.X, w.Y+vloc.Y, char, nil, curStyle)
|
||||
vloc.X++
|
||||
}
|
||||
nColsBeforeStart--
|
||||
draw(char, curStyle)
|
||||
}
|
||||
}
|
||||
totalwidth += width
|
||||
@@ -195,12 +214,12 @@ func (w *Window) DisplayBuffer() {
|
||||
}
|
||||
vloc.X = 0
|
||||
// This will draw an empty line number because the current line is wrapped
|
||||
w.DrawLineNum(lineNumStyle, true, maxLineNumLength, &vloc, &bloc)
|
||||
w.drawLineNum(lineNumStyle, true, maxLineNumLength, &vloc, &bloc)
|
||||
}
|
||||
}
|
||||
}
|
||||
if w.Buf.GetActiveCursor().X == bloc.X && w.Buf.GetActiveCursor().Y == bloc.Y {
|
||||
w.ShowCursor(vloc.X, vloc.Y, true)
|
||||
if activeC.X == bloc.X && activeC.Y == bloc.Y {
|
||||
w.showCursor(vloc.X, vloc.Y, true)
|
||||
}
|
||||
bloc.X = w.StartCol
|
||||
bloc.Y++
|
||||
@@ -210,6 +229,11 @@ func (w *Window) DisplayBuffer() {
|
||||
}
|
||||
}
|
||||
|
||||
func (w *Window) DisplayStatusLine() {
|
||||
func (w *BufWindow) displayStatusLine() {
|
||||
w.sline.Display()
|
||||
}
|
||||
|
||||
func (w *BufWindow) Display() {
|
||||
w.displayBuffer()
|
||||
w.displayStatusLine()
|
||||
}
|
||||
20
cmd/micro/editpane.go
Normal file
20
cmd/micro/editpane.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/zyedidia/micro/cmd/micro/action"
|
||||
"github.com/zyedidia/micro/cmd/micro/buffer"
|
||||
"github.com/zyedidia/micro/cmd/micro/display"
|
||||
)
|
||||
|
||||
type EditPane struct {
|
||||
display.Window
|
||||
action.Handler
|
||||
}
|
||||
|
||||
func NewBufEditPane(x, y, width, height int, b *buffer.Buffer) *EditPane {
|
||||
e := new(EditPane)
|
||||
e.Window = display.NewBufWindow(x, y, width, height, b)
|
||||
e.Handler = action.NewBufHandler(b)
|
||||
|
||||
return e
|
||||
}
|
||||
@@ -78,7 +78,7 @@ func Import(pkg string) *lua.LTable {
|
||||
func importFmt() *lua.LTable {
|
||||
pkg := L.NewTable()
|
||||
|
||||
L.SetField(pkg, "tErrorf", luar.New(L, fmt.Errorf))
|
||||
L.SetField(pkg, "Errorf", luar.New(L, fmt.Errorf))
|
||||
L.SetField(pkg, "Fprint", luar.New(L, fmt.Fprint))
|
||||
L.SetField(pkg, "Fprintf", luar.New(L, fmt.Fprintf))
|
||||
L.SetField(pkg, "Fprintln", luar.New(L, fmt.Fprintln))
|
||||
|
||||
@@ -3,9 +3,12 @@ package main
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/go-errors/errors"
|
||||
isatty "github.com/mattn/go-isatty"
|
||||
"github.com/zyedidia/micro/cmd/micro/action"
|
||||
"github.com/zyedidia/micro/cmd/micro/buffer"
|
||||
"github.com/zyedidia/micro/cmd/micro/config"
|
||||
@@ -20,8 +23,9 @@ const (
|
||||
)
|
||||
|
||||
var (
|
||||
// Version is the version number or commit hash
|
||||
// These variables should be set by the linker when compiling
|
||||
|
||||
// Version is the version number or commit hash
|
||||
Version = "0.0.0-unknown"
|
||||
// CommitHash is the commit this version was built on
|
||||
CommitHash = "Unknown"
|
||||
@@ -34,9 +38,6 @@ var (
|
||||
events chan tcell.Event
|
||||
autosave chan bool
|
||||
|
||||
// How many redraws have happened
|
||||
numRedraw uint
|
||||
|
||||
// Command line flags
|
||||
flagVersion = flag.Bool("version", false, "Show the version number and information")
|
||||
flagStartPos = flag.String("startpos", "", "LINE,COL to start the cursor at when opening a buffer.")
|
||||
@@ -91,6 +92,66 @@ func InitFlags() {
|
||||
}
|
||||
}
|
||||
|
||||
// LoadInput determines which files should be loaded into buffers
|
||||
// based on the input stored in flag.Args()
|
||||
func LoadInput() []*buffer.Buffer {
|
||||
// There are a number of ways micro should start given its input
|
||||
|
||||
// 1. If it is given a files in flag.Args(), it should open those
|
||||
|
||||
// 2. If there is no input file and the input is not a terminal, that means
|
||||
// something is being piped in and the stdin should be opened in an
|
||||
// empty buffer
|
||||
|
||||
// 3. If there is no input file and the input is a terminal, an empty buffer
|
||||
// should be opened
|
||||
|
||||
var filename string
|
||||
var input []byte
|
||||
var err error
|
||||
args := flag.Args()
|
||||
buffers := make([]*buffer.Buffer, 0, len(args))
|
||||
|
||||
if len(args) > 0 {
|
||||
// Option 1
|
||||
// We go through each file and load it
|
||||
for i := 0; i < len(args); i++ {
|
||||
if strings.HasPrefix(args[i], "+") {
|
||||
if strings.Contains(args[i], ":") {
|
||||
split := strings.Split(args[i], ":")
|
||||
*flagStartPos = split[0][1:] + "," + split[1]
|
||||
} else {
|
||||
*flagStartPos = args[i][1:] + ",0"
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
buf, err := buffer.NewBufferFromFile(args[i])
|
||||
if err != nil {
|
||||
util.TermMessage(err)
|
||||
continue
|
||||
}
|
||||
// If the file didn't exist, input will be empty, and we'll open an empty buffer
|
||||
buffers = append(buffers, buf)
|
||||
}
|
||||
} else if !isatty.IsTerminal(os.Stdin.Fd()) {
|
||||
// Option 2
|
||||
// The input is not a terminal, so something is being piped in
|
||||
// and we should read from stdin
|
||||
input, err = ioutil.ReadAll(os.Stdin)
|
||||
if err != nil {
|
||||
util.TermMessage("Error reading from stdin: ", err)
|
||||
input = []byte{}
|
||||
}
|
||||
buffers = append(buffers, buffer.NewBufferFromString(string(input), filename))
|
||||
} else {
|
||||
// Option 3, just open an empty buffer
|
||||
buffers = append(buffers, buffer.NewBufferFromString(string(input), filename))
|
||||
}
|
||||
|
||||
return buffers
|
||||
}
|
||||
|
||||
func main() {
|
||||
var err error
|
||||
|
||||
@@ -127,18 +188,9 @@ func main() {
|
||||
}
|
||||
}()
|
||||
|
||||
action.TryBindKey("Ctrl-z", "Undo", true)
|
||||
|
||||
b, err := buffer.NewBufferFromFile(os.Args[1])
|
||||
|
||||
if err != nil {
|
||||
util.TermMessage(err)
|
||||
}
|
||||
|
||||
b := LoadInput()[0]
|
||||
width, height := screen.Screen.Size()
|
||||
w := NewWindow(0, 0, width, height-1, b)
|
||||
|
||||
a := action.NewBufHandler(b)
|
||||
ep := NewBufEditPane(0, 0, width, height-1, b)
|
||||
|
||||
// Here is the event loop which runs in a separate thread
|
||||
go func() {
|
||||
@@ -153,8 +205,7 @@ func main() {
|
||||
for {
|
||||
// Display everything
|
||||
screen.Screen.Fill(' ', config.DefStyle)
|
||||
w.DisplayBuffer()
|
||||
w.DisplayStatusLine()
|
||||
ep.Display()
|
||||
screen.Screen.Show()
|
||||
|
||||
var event tcell.Event
|
||||
@@ -165,7 +216,7 @@ func main() {
|
||||
}
|
||||
|
||||
if event != nil {
|
||||
a.HandleEvent(event)
|
||||
ep.HandleEvent(event)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -135,13 +135,8 @@ func FSize(f *os.File) int64 {
|
||||
// IsWordChar returns whether or not the string is a 'word character'
|
||||
// If it is a unicode character, then it does not match
|
||||
// Word characters are defined as [A-Za-z0-9_]
|
||||
func IsWordChar(str string) bool {
|
||||
if len(str) > 1 {
|
||||
// Unicode
|
||||
return true
|
||||
}
|
||||
c := str[0]
|
||||
return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c == '_')
|
||||
func IsWordChar(r rune) bool {
|
||||
return (r >= '0' && r <= '9') || (r >= 'A' && r <= 'Z') || (r >= 'a' && r <= 'z') || (r == '_')
|
||||
}
|
||||
|
||||
// IsWhitespace returns true if the given rune is a space, tab, or newline
|
||||
|
||||
Reference in New Issue
Block a user