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
|
||||
// visual positions for mouse clicks and scrolling
|
||||
type BufHandler struct {
|
||||
display.Window
|
||||
display.BWindow
|
||||
|
||||
Buf *buffer.Buffer
|
||||
|
||||
@@ -98,10 +98,10 @@ type BufHandler struct {
|
||||
splitID uint64
|
||||
}
|
||||
|
||||
func NewBufHandler(buf *buffer.Buffer, win display.Window) *BufHandler {
|
||||
func NewBufHandler(buf *buffer.Buffer, win display.BWindow) *BufHandler {
|
||||
h := new(BufHandler)
|
||||
h.Buf = buf
|
||||
h.Window = win
|
||||
h.BWindow = win
|
||||
|
||||
h.Cursor = h.Buf.GetActiveCursor()
|
||||
h.mouseReleased = true
|
||||
@@ -109,6 +109,23 @@ func NewBufHandler(buf *buffer.Buffer, win display.Window) *BufHandler {
|
||||
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 {
|
||||
return h.splitID
|
||||
}
|
||||
|
||||
@@ -2,6 +2,9 @@ package action
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/zyedidia/micro/cmd/micro/buffer"
|
||||
"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
|
||||
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
|
||||
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
|
||||
@@ -181,6 +229,39 @@ func (h *BufHandler) PwdCmd(args []string) {
|
||||
|
||||
// OpenCmd opens a new buffer with a given filename
|
||||
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
|
||||
@@ -341,6 +422,24 @@ func (h *BufHandler) SetLocalCmd(args []string) {
|
||||
|
||||
// ShowCmd shows the value of the given option
|
||||
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
|
||||
@@ -376,10 +475,12 @@ func (h *BufHandler) RunCmd(args []string) {
|
||||
|
||||
// QuitCmd closes the main view
|
||||
func (h *BufHandler) QuitCmd(args []string) {
|
||||
h.Quit()
|
||||
}
|
||||
|
||||
// SaveCmd saves the buffer in the main view
|
||||
func (h *BufHandler) SaveCmd(args []string) {
|
||||
h.Save()
|
||||
}
|
||||
|
||||
// ReplaceCmd runs search and replace
|
||||
|
||||
@@ -15,7 +15,7 @@ type InfoHandler struct {
|
||||
*info.InfoBuf
|
||||
}
|
||||
|
||||
func NewInfoHandler(ib *info.InfoBuf, w display.Window) *InfoHandler {
|
||||
func NewInfoHandler(ib *info.InfoBuf, w display.BWindow) *InfoHandler {
|
||||
ih := new(InfoHandler)
|
||||
ih.InfoBuf = ib
|
||||
ih.BufHandler = NewBufHandler(ib.Buffer, w)
|
||||
|
||||
@@ -15,12 +15,12 @@ type Pane interface {
|
||||
}
|
||||
|
||||
type EditPane struct {
|
||||
display.Window
|
||||
display.BWindow
|
||||
*BufHandler
|
||||
}
|
||||
|
||||
type InfoPane struct {
|
||||
display.Window
|
||||
display.BWindow
|
||||
*InfoHandler
|
||||
*info.InfoBuf
|
||||
}
|
||||
@@ -29,7 +29,7 @@ func NewBufEditPane(x, y, width, height int, b *buffer.Buffer) *EditPane {
|
||||
e := new(EditPane)
|
||||
// TODO: can probably replace editpane with bufhandler entirely
|
||||
w := display.NewBufWindow(x, y, width, height, b)
|
||||
e.Window = w
|
||||
e.BWindow = w
|
||||
e.BufHandler = NewBufHandler(b, w)
|
||||
|
||||
return e
|
||||
@@ -39,7 +39,7 @@ func NewInfoBar() *InfoPane {
|
||||
e := new(InfoPane)
|
||||
ib := info.NewBuffer()
|
||||
w := display.NewInfoWindow(ib)
|
||||
e.Window = w
|
||||
e.BWindow = w
|
||||
e.InfoHandler = NewInfoHandler(ib, w)
|
||||
e.InfoBuf = ib
|
||||
|
||||
|
||||
@@ -133,13 +133,15 @@ func NewBuffer(reader io.Reader, size int64, path string, cursorPosition []strin
|
||||
config.InitLocalSettings(b.Settings, b.Path)
|
||||
|
||||
found := false
|
||||
for _, buf := range OpenBuffers {
|
||||
if buf.AbsPath == absPath {
|
||||
found = true
|
||||
b.LineArray = buf.LineArray
|
||||
b.EventHandler = buf.EventHandler
|
||||
b.ModTime = buf.ModTime
|
||||
b.isModified = buf.isModified
|
||||
if len(path) > 0 {
|
||||
for _, buf := range OpenBuffers {
|
||||
if buf.AbsPath == absPath {
|
||||
found = true
|
||||
b.LineArray = buf.LineArray
|
||||
b.EventHandler = buf.EventHandler
|
||||
b.ModTime = buf.ModTime
|
||||
b.isModified = buf.isModified
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -41,6 +41,10 @@ func NewBufWindow(x, y, width, height int, buf *buffer.Buffer) *BufWindow {
|
||||
return w
|
||||
}
|
||||
|
||||
func (w *BufWindow) SetBuffer(b *buffer.Buffer) {
|
||||
w.Buf = b
|
||||
}
|
||||
|
||||
func (v *View) GetView() *View {
|
||||
return v
|
||||
}
|
||||
|
||||
@@ -53,6 +53,10 @@ func (i *InfoWindow) Resize(w, h int) {
|
||||
i.y = h
|
||||
}
|
||||
|
||||
func (i *InfoWindow) SetBuffer(b *buffer.Buffer) {
|
||||
i.InfoBuf.Buffer = b
|
||||
}
|
||||
|
||||
// func (i *InfoWindow) YesNoPrompt() (bool, bool) {
|
||||
// for {
|
||||
// i.Clear()
|
||||
|
||||
@@ -24,3 +24,8 @@ type Window interface {
|
||||
Resize(w, h int)
|
||||
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])
|
||||
}
|
||||
|
||||
// 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
|
||||
// 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 '~'.
|
||||
|
||||
Reference in New Issue
Block a user