mirror of
https://github.com/zyedidia/micro.git
synced 2026-02-04 14:10:23 +09:00
Add some commands
This commit is contained in:
@@ -53,7 +53,7 @@ func BufMapMouse(k MouseEvent, action string) {
|
|||||||
// The ActionHandler can access the window for necessary info about
|
// The ActionHandler can access the window for necessary info about
|
||||||
// visual positions for mouse clicks and scrolling
|
// visual positions for mouse clicks and scrolling
|
||||||
type BufHandler struct {
|
type BufHandler struct {
|
||||||
display.Window
|
display.BWindow
|
||||||
|
|
||||||
Buf *buffer.Buffer
|
Buf *buffer.Buffer
|
||||||
|
|
||||||
@@ -98,10 +98,10 @@ type BufHandler struct {
|
|||||||
splitID uint64
|
splitID uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewBufHandler(buf *buffer.Buffer, win display.Window) *BufHandler {
|
func NewBufHandler(buf *buffer.Buffer, win display.BWindow) *BufHandler {
|
||||||
h := new(BufHandler)
|
h := new(BufHandler)
|
||||||
h.Buf = buf
|
h.Buf = buf
|
||||||
h.Window = win
|
h.BWindow = win
|
||||||
|
|
||||||
h.Cursor = h.Buf.GetActiveCursor()
|
h.Cursor = h.Buf.GetActiveCursor()
|
||||||
h.mouseReleased = true
|
h.mouseReleased = true
|
||||||
@@ -109,6 +109,23 @@ func NewBufHandler(buf *buffer.Buffer, win display.Window) *BufHandler {
|
|||||||
return h
|
return h
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *BufHandler) OpenBuffer(b *buffer.Buffer) {
|
||||||
|
h.Buf.Close()
|
||||||
|
h.Buf = b
|
||||||
|
h.BWindow.SetBuffer(b)
|
||||||
|
h.Cursor = b.GetActiveCursor()
|
||||||
|
v := new(display.View)
|
||||||
|
h.SetView(v)
|
||||||
|
h.Relocate()
|
||||||
|
// Set mouseReleased to true because we assume the mouse is not being pressed when
|
||||||
|
// the editor is opened
|
||||||
|
h.mouseReleased = true
|
||||||
|
// Set isOverwriteMode to false, because we assume we are in the default mode when editor
|
||||||
|
// is opened
|
||||||
|
h.isOverwriteMode = false
|
||||||
|
h.lastClickTime = time.Time{}
|
||||||
|
}
|
||||||
|
|
||||||
func (h *BufHandler) ID() uint64 {
|
func (h *BufHandler) ID() uint64 {
|
||||||
return h.splitID
|
return h.splitID
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,9 @@ package action
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/zyedidia/micro/cmd/micro/buffer"
|
"github.com/zyedidia/micro/cmd/micro/buffer"
|
||||||
"github.com/zyedidia/micro/cmd/micro/config"
|
"github.com/zyedidia/micro/cmd/micro/config"
|
||||||
@@ -152,10 +155,55 @@ func (h *BufHandler) RawCmd(args []string) {
|
|||||||
|
|
||||||
// TabSwitchCmd switches to a given tab either by name or by number
|
// TabSwitchCmd switches to a given tab either by name or by number
|
||||||
func (h *BufHandler) TabSwitchCmd(args []string) {
|
func (h *BufHandler) TabSwitchCmd(args []string) {
|
||||||
|
if len(args) > 0 {
|
||||||
|
num, err := strconv.Atoi(args[0])
|
||||||
|
if err != nil {
|
||||||
|
// Check for tab with this name
|
||||||
|
|
||||||
|
found := false
|
||||||
|
for i, t := range Tabs.List {
|
||||||
|
if t.Panes[t.active].Name() == args[0] {
|
||||||
|
Tabs.SetActive(i)
|
||||||
|
found = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
|
InfoBar.Error("Could not find tab: ", err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
num--
|
||||||
|
if num >= 0 && num < len(Tabs.List) {
|
||||||
|
Tabs.SetActive(num)
|
||||||
|
} else {
|
||||||
|
InfoBar.Error("Invalid tab index")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// CdCmd changes the current working directory
|
// CdCmd changes the current working directory
|
||||||
func (h *BufHandler) CdCmd(args []string) {
|
func (h *BufHandler) CdCmd(args []string) {
|
||||||
|
if len(args) > 0 {
|
||||||
|
path, err := util.ReplaceHome(args[0])
|
||||||
|
if err != nil {
|
||||||
|
InfoBar.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = os.Chdir(path)
|
||||||
|
if err != nil {
|
||||||
|
InfoBar.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
wd, _ := os.Getwd()
|
||||||
|
for _, b := range buffer.OpenBuffers {
|
||||||
|
if len(b.Path) > 0 {
|
||||||
|
b.Path, _ = util.MakeRelative(b.AbsPath, wd)
|
||||||
|
if p, _ := filepath.Abs(b.Path); !strings.Contains(p, wd) {
|
||||||
|
b.Path = b.AbsPath
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MemUsageCmd prints micro's memory usage
|
// MemUsageCmd prints micro's memory usage
|
||||||
@@ -181,6 +229,39 @@ func (h *BufHandler) PwdCmd(args []string) {
|
|||||||
|
|
||||||
// OpenCmd opens a new buffer with a given filename
|
// OpenCmd opens a new buffer with a given filename
|
||||||
func (h *BufHandler) OpenCmd(args []string) {
|
func (h *BufHandler) OpenCmd(args []string) {
|
||||||
|
if len(args) > 0 {
|
||||||
|
filename := args[0]
|
||||||
|
// the filename might or might not be quoted, so unquote first then join the strings.
|
||||||
|
args, err := shellwords.Split(filename)
|
||||||
|
if err != nil {
|
||||||
|
InfoBar.Error("Error parsing args ", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
filename = strings.Join(args, " ")
|
||||||
|
|
||||||
|
open := func() {
|
||||||
|
b, err := buffer.NewBufferFromFile(filename, buffer.BTDefault)
|
||||||
|
if err != nil {
|
||||||
|
InfoBar.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
h.OpenBuffer(b)
|
||||||
|
}
|
||||||
|
if h.Buf.Modified() {
|
||||||
|
InfoBar.YNPrompt("Save changes to "+h.Buf.GetName()+" before closing? (y,n,esc)", func(yes, canceled bool) {
|
||||||
|
if !canceled && !yes {
|
||||||
|
open()
|
||||||
|
} else if !canceled && yes {
|
||||||
|
h.Save()
|
||||||
|
open()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
open()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
InfoBar.Error("No filename")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToggleLogCmd toggles the log view
|
// ToggleLogCmd toggles the log view
|
||||||
@@ -341,6 +422,24 @@ func (h *BufHandler) SetLocalCmd(args []string) {
|
|||||||
|
|
||||||
// ShowCmd shows the value of the given option
|
// ShowCmd shows the value of the given option
|
||||||
func (h *BufHandler) ShowCmd(args []string) {
|
func (h *BufHandler) ShowCmd(args []string) {
|
||||||
|
if len(args) < 1 {
|
||||||
|
InfoBar.Error("Please provide an option to show")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var option interface{}
|
||||||
|
if opt, ok := h.Buf.Settings[args[0]]; ok {
|
||||||
|
option = opt
|
||||||
|
} else if opt, ok := config.GlobalSettings[args[0]]; ok {
|
||||||
|
option = opt
|
||||||
|
}
|
||||||
|
|
||||||
|
if option == nil {
|
||||||
|
InfoBar.Error(args[0], " is not a valid option")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
InfoBar.Message(option)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ShowKeyCmd displays the action that a key is bound to
|
// ShowKeyCmd displays the action that a key is bound to
|
||||||
@@ -376,10 +475,12 @@ func (h *BufHandler) RunCmd(args []string) {
|
|||||||
|
|
||||||
// QuitCmd closes the main view
|
// QuitCmd closes the main view
|
||||||
func (h *BufHandler) QuitCmd(args []string) {
|
func (h *BufHandler) QuitCmd(args []string) {
|
||||||
|
h.Quit()
|
||||||
}
|
}
|
||||||
|
|
||||||
// SaveCmd saves the buffer in the main view
|
// SaveCmd saves the buffer in the main view
|
||||||
func (h *BufHandler) SaveCmd(args []string) {
|
func (h *BufHandler) SaveCmd(args []string) {
|
||||||
|
h.Save()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReplaceCmd runs search and replace
|
// ReplaceCmd runs search and replace
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ type InfoHandler struct {
|
|||||||
*info.InfoBuf
|
*info.InfoBuf
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewInfoHandler(ib *info.InfoBuf, w display.Window) *InfoHandler {
|
func NewInfoHandler(ib *info.InfoBuf, w display.BWindow) *InfoHandler {
|
||||||
ih := new(InfoHandler)
|
ih := new(InfoHandler)
|
||||||
ih.InfoBuf = ib
|
ih.InfoBuf = ib
|
||||||
ih.BufHandler = NewBufHandler(ib.Buffer, w)
|
ih.BufHandler = NewBufHandler(ib.Buffer, w)
|
||||||
|
|||||||
@@ -15,12 +15,12 @@ type Pane interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type EditPane struct {
|
type EditPane struct {
|
||||||
display.Window
|
display.BWindow
|
||||||
*BufHandler
|
*BufHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
type InfoPane struct {
|
type InfoPane struct {
|
||||||
display.Window
|
display.BWindow
|
||||||
*InfoHandler
|
*InfoHandler
|
||||||
*info.InfoBuf
|
*info.InfoBuf
|
||||||
}
|
}
|
||||||
@@ -29,7 +29,7 @@ func NewBufEditPane(x, y, width, height int, b *buffer.Buffer) *EditPane {
|
|||||||
e := new(EditPane)
|
e := new(EditPane)
|
||||||
// TODO: can probably replace editpane with bufhandler entirely
|
// TODO: can probably replace editpane with bufhandler entirely
|
||||||
w := display.NewBufWindow(x, y, width, height, b)
|
w := display.NewBufWindow(x, y, width, height, b)
|
||||||
e.Window = w
|
e.BWindow = w
|
||||||
e.BufHandler = NewBufHandler(b, w)
|
e.BufHandler = NewBufHandler(b, w)
|
||||||
|
|
||||||
return e
|
return e
|
||||||
@@ -39,7 +39,7 @@ func NewInfoBar() *InfoPane {
|
|||||||
e := new(InfoPane)
|
e := new(InfoPane)
|
||||||
ib := info.NewBuffer()
|
ib := info.NewBuffer()
|
||||||
w := display.NewInfoWindow(ib)
|
w := display.NewInfoWindow(ib)
|
||||||
e.Window = w
|
e.BWindow = w
|
||||||
e.InfoHandler = NewInfoHandler(ib, w)
|
e.InfoHandler = NewInfoHandler(ib, w)
|
||||||
e.InfoBuf = ib
|
e.InfoBuf = ib
|
||||||
|
|
||||||
|
|||||||
@@ -133,6 +133,7 @@ func NewBuffer(reader io.Reader, size int64, path string, cursorPosition []strin
|
|||||||
config.InitLocalSettings(b.Settings, b.Path)
|
config.InitLocalSettings(b.Settings, b.Path)
|
||||||
|
|
||||||
found := false
|
found := false
|
||||||
|
if len(path) > 0 {
|
||||||
for _, buf := range OpenBuffers {
|
for _, buf := range OpenBuffers {
|
||||||
if buf.AbsPath == absPath {
|
if buf.AbsPath == absPath {
|
||||||
found = true
|
found = true
|
||||||
@@ -142,6 +143,7 @@ func NewBuffer(reader io.Reader, size int64, path string, cursorPosition []strin
|
|||||||
b.isModified = buf.isModified
|
b.isModified = buf.isModified
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if !found {
|
if !found {
|
||||||
b.LineArray = NewLineArray(uint64(size), FFAuto, reader)
|
b.LineArray = NewLineArray(uint64(size), FFAuto, reader)
|
||||||
|
|||||||
@@ -41,6 +41,10 @@ func NewBufWindow(x, y, width, height int, buf *buffer.Buffer) *BufWindow {
|
|||||||
return w
|
return w
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *BufWindow) SetBuffer(b *buffer.Buffer) {
|
||||||
|
w.Buf = b
|
||||||
|
}
|
||||||
|
|
||||||
func (v *View) GetView() *View {
|
func (v *View) GetView() *View {
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,6 +53,10 @@ func (i *InfoWindow) Resize(w, h int) {
|
|||||||
i.y = h
|
i.y = h
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (i *InfoWindow) SetBuffer(b *buffer.Buffer) {
|
||||||
|
i.InfoBuf.Buffer = b
|
||||||
|
}
|
||||||
|
|
||||||
// func (i *InfoWindow) YesNoPrompt() (bool, bool) {
|
// func (i *InfoWindow) YesNoPrompt() (bool, bool) {
|
||||||
// for {
|
// for {
|
||||||
// i.Clear()
|
// i.Clear()
|
||||||
|
|||||||
@@ -24,3 +24,8 @@ type Window interface {
|
|||||||
Resize(w, h int)
|
Resize(w, h int)
|
||||||
SetActive(b bool)
|
SetActive(b bool)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type BWindow interface {
|
||||||
|
Window
|
||||||
|
SetBuffer(b *buffer.Buffer)
|
||||||
|
}
|
||||||
|
|||||||
@@ -195,6 +195,18 @@ func RunePos(b []byte, i int) int {
|
|||||||
return utf8.RuneCount(b[:i])
|
return utf8.RuneCount(b[:i])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MakeRelative will attempt to make a relative path between path and base
|
||||||
|
func MakeRelative(path, base string) (string, error) {
|
||||||
|
if len(path) > 0 {
|
||||||
|
rel, err := filepath.Rel(base, path)
|
||||||
|
if err != nil {
|
||||||
|
return path, err
|
||||||
|
}
|
||||||
|
return rel, nil
|
||||||
|
}
|
||||||
|
return path, nil
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: consider changing because of snap segfault
|
// TODO: consider changing because of snap segfault
|
||||||
// ReplaceHome takes a path as input and replaces ~ at the start of the path with the user's
|
// ReplaceHome takes a path as input and replaces ~ at the start of the path with the user's
|
||||||
// home directory. Does nothing if the path does not start with '~'.
|
// home directory. Does nothing if the path does not start with '~'.
|
||||||
|
|||||||
Reference in New Issue
Block a user