mirror of
https://github.com/zyedidia/micro
synced 2024-11-05 17:41:24 +00:00
parent
67355337b3
commit
f143418267
16 changed files with 403 additions and 61 deletions
|
@ -16,6 +16,7 @@ import (
|
|||
lua "github.com/yuin/gopher-lua"
|
||||
"github.com/zyedidia/micro/v2/internal/action"
|
||||
"github.com/zyedidia/micro/v2/internal/buffer"
|
||||
"github.com/zyedidia/micro/v2/internal/clipboard"
|
||||
"github.com/zyedidia/micro/v2/internal/config"
|
||||
ulua "github.com/zyedidia/micro/v2/internal/lua"
|
||||
"github.com/zyedidia/micro/v2/internal/screen"
|
||||
|
@ -269,6 +270,9 @@ func main() {
|
|||
os.Exit(1)
|
||||
}
|
||||
|
||||
m := clipboard.SetMethod(config.GetGlobalOption("clipboard").(string))
|
||||
clipErr := clipboard.Initialize(m)
|
||||
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
screen.Screen.Fini()
|
||||
|
@ -313,6 +317,10 @@ func main() {
|
|||
screen.TermMessage(err)
|
||||
}
|
||||
|
||||
if clipErr != nil {
|
||||
action.InfoBar.Error(clipErr, " or change 'clipboard' option")
|
||||
}
|
||||
|
||||
events = make(chan tcell.Event)
|
||||
|
||||
// Here is the event loop which runs in a separate thread
|
||||
|
|
4
go.mod
4
go.mod
|
@ -12,12 +12,12 @@ require (
|
|||
github.com/sergi/go-diff v1.1.0
|
||||
github.com/stretchr/testify v1.4.0
|
||||
github.com/yuin/gopher-lua v0.0.0-20191220021717-ab39c6098bdb
|
||||
github.com/zyedidia/clipboard v1.0.1
|
||||
github.com/zyedidia/clipboard v1.0.3
|
||||
github.com/zyedidia/glob v0.0.0-20170209203856-dd4023a66dc3
|
||||
github.com/zyedidia/highlight v0.0.0-20170330143449-201131ce5cf5
|
||||
github.com/zyedidia/json5 v0.0.0-20200102012142-2da050b1a98d
|
||||
github.com/zyedidia/pty v2.0.0+incompatible // indirect
|
||||
github.com/zyedidia/tcell v1.4.8
|
||||
github.com/zyedidia/tcell v1.4.9
|
||||
github.com/zyedidia/terminal v0.0.0-20180726154117-533c623e2415
|
||||
golang.org/x/text v0.3.2
|
||||
gopkg.in/sourcemap.v1 v1.0.5 // indirect
|
||||
|
|
6
go.sum
6
go.sum
|
@ -40,6 +40,10 @@ github.com/yuin/gopher-lua v0.0.0-20191220021717-ab39c6098bdb h1:ZkM6LRnq40pR1Ox
|
|||
github.com/yuin/gopher-lua v0.0.0-20191220021717-ab39c6098bdb/go.mod h1:gqRgreBUhTSL0GeU64rtZ3Uq3wtjOa/TB2YfrtkCbVQ=
|
||||
github.com/zyedidia/clipboard v1.0.1 h1:DNsDMRXdptfdp4f6gSnSNJpWadAgI8UCm26elADCYak=
|
||||
github.com/zyedidia/clipboard v1.0.1/go.mod h1:zykFnZUXX0ErxqvYLUFEq7QDJKId8rmh2FgD0/Y8cjA=
|
||||
github.com/zyedidia/clipboard v1.0.2 h1:Mh5t+hjEf9I5pcveVxVAFJsuOhd2ByavDgIkflK3Qps=
|
||||
github.com/zyedidia/clipboard v1.0.2/go.mod h1:zykFnZUXX0ErxqvYLUFEq7QDJKId8rmh2FgD0/Y8cjA=
|
||||
github.com/zyedidia/clipboard v1.0.3 h1:F/nCDVYMdbDWTmY8s8cJl0tnwX32q96IF09JHM14bUI=
|
||||
github.com/zyedidia/clipboard v1.0.3/go.mod h1:zykFnZUXX0ErxqvYLUFEq7QDJKId8rmh2FgD0/Y8cjA=
|
||||
github.com/zyedidia/glob v0.0.0-20170209203856-dd4023a66dc3 h1:oMHjjTLfGXVuyOQBYj5/td9WC0mw4g1xDBPovIqmHew=
|
||||
github.com/zyedidia/glob v0.0.0-20170209203856-dd4023a66dc3/go.mod h1:YKbIYP//Eln8eDgAJGI3IDvR3s4Tv9Z9TGIOumiyQ5c=
|
||||
github.com/zyedidia/go-shellquote v0.0.0-20200613203517-eccd813c0655 h1:Z3RhH6hvcSx7eX6Q/pP6YVsgea/1eMDG99vtWwi3nK4=
|
||||
|
@ -54,6 +58,8 @@ github.com/zyedidia/pty v2.0.0+incompatible h1:Ou5vXL6tvjst+RV8sUFISbuKDnUJPhnpy
|
|||
github.com/zyedidia/pty v2.0.0+incompatible/go.mod h1:4y9l9yJZNxRa7GB/fB+mmDmGkG3CqmzLf4vUxGGotEA=
|
||||
github.com/zyedidia/tcell v1.4.8 h1:s4zYGOyCNDK4cdrgNVME0SxGizuT/oKY3OyB4Ls2Qpg=
|
||||
github.com/zyedidia/tcell v1.4.8/go.mod h1:HhlbMSCcGX15rFDB+Q1Lk3pKEOocsCUAQC3zhZ9sadA=
|
||||
github.com/zyedidia/tcell v1.4.9 h1:DYUrd8gCmSxUlbFd280sT6tzEqhxfyWMbZNNnup6iQ0=
|
||||
github.com/zyedidia/tcell v1.4.9/go.mod h1:HhlbMSCcGX15rFDB+Q1Lk3pKEOocsCUAQC3zhZ9sadA=
|
||||
github.com/zyedidia/terminal v0.0.0-20180726154117-533c623e2415 h1:752dTQ5OatJ9M5ULK2+9lor+nzyZz+LYDo3WGngg3Rc=
|
||||
github.com/zyedidia/terminal v0.0.0-20180726154117-533c623e2415/go.mod h1:8leT8G0Cm8NoJHdrrKHyR9MirWoF4YW7pZh06B6H+1E=
|
||||
golang.org/x/sys v0.0.0-20190204203706-41f3e6584952/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
|
|
|
@ -7,8 +7,8 @@ import (
|
|||
"time"
|
||||
|
||||
shellquote "github.com/kballard/go-shellquote"
|
||||
"github.com/zyedidia/clipboard"
|
||||
"github.com/zyedidia/micro/v2/internal/buffer"
|
||||
"github.com/zyedidia/micro/v2/internal/clipboard"
|
||||
"github.com/zyedidia/micro/v2/internal/config"
|
||||
"github.com/zyedidia/micro/v2/internal/screen"
|
||||
"github.com/zyedidia/micro/v2/internal/shell"
|
||||
|
@ -59,7 +59,7 @@ func (h *BufPane) MousePress(e *tcell.EventMouse) bool {
|
|||
h.doubleClick = false
|
||||
|
||||
h.Cursor.SelectLine()
|
||||
h.Cursor.CopySelection("primary")
|
||||
h.Cursor.CopySelection(clipboard.PrimaryReg)
|
||||
} else {
|
||||
// Double click
|
||||
h.lastClickTime = time.Now()
|
||||
|
@ -68,7 +68,7 @@ func (h *BufPane) MousePress(e *tcell.EventMouse) bool {
|
|||
h.tripleClick = false
|
||||
|
||||
h.Cursor.SelectWord()
|
||||
h.Cursor.CopySelection("primary")
|
||||
h.Cursor.CopySelection(clipboard.PrimaryReg)
|
||||
}
|
||||
} else {
|
||||
h.doubleClick = false
|
||||
|
@ -961,13 +961,9 @@ func (h *BufPane) Redo() bool {
|
|||
// Copy the selection to the system clipboard
|
||||
func (h *BufPane) Copy() bool {
|
||||
if h.Cursor.HasSelection() {
|
||||
h.Cursor.CopySelection("clipboard")
|
||||
h.Cursor.CopySelection(clipboard.ClipboardReg)
|
||||
h.freshClip = true
|
||||
if clipboard.Unsupported {
|
||||
InfoBar.Message("Copied selection (install xclip for external clipboard)")
|
||||
} else {
|
||||
InfoBar.Message("Copied selection")
|
||||
}
|
||||
InfoBar.Message("Copied selection")
|
||||
}
|
||||
h.Relocate()
|
||||
return true
|
||||
|
@ -979,13 +975,9 @@ func (h *BufPane) CopyLine() bool {
|
|||
return false
|
||||
} else {
|
||||
h.Cursor.SelectLine()
|
||||
h.Cursor.CopySelection("clipboard")
|
||||
h.Cursor.CopySelection(clipboard.ClipboardReg)
|
||||
h.freshClip = true
|
||||
if clipboard.Unsupported {
|
||||
InfoBar.Message("Copied line (install xclip for external clipboard)")
|
||||
} else {
|
||||
InfoBar.Message("Copied line")
|
||||
}
|
||||
InfoBar.Message("Copied line")
|
||||
}
|
||||
h.Cursor.Deselect(true)
|
||||
h.Relocate()
|
||||
|
@ -1000,10 +992,10 @@ func (h *BufPane) CutLine() bool {
|
|||
}
|
||||
if h.freshClip == true {
|
||||
if h.Cursor.HasSelection() {
|
||||
if clip, err := clipboard.ReadAll("clipboard"); err != nil {
|
||||
// messenger.Error(err)
|
||||
if clip, err := clipboard.Read(clipboard.ClipboardReg); err != nil {
|
||||
InfoBar.Error(err)
|
||||
} else {
|
||||
clipboard.WriteAll(clip+string(h.Cursor.GetSelection()), "clipboard")
|
||||
clipboard.Write(clip+string(h.Cursor.GetSelection()), clipboard.ClipboardReg)
|
||||
}
|
||||
}
|
||||
} else if time.Since(h.lastCutTime)/time.Second > 10*time.Second || h.freshClip == false {
|
||||
|
@ -1021,7 +1013,7 @@ func (h *BufPane) CutLine() bool {
|
|||
// Cut the selection to the system clipboard
|
||||
func (h *BufPane) Cut() bool {
|
||||
if h.Cursor.HasSelection() {
|
||||
h.Cursor.CopySelection("clipboard")
|
||||
h.Cursor.CopySelection(clipboard.ClipboardReg)
|
||||
h.Cursor.DeleteSelection()
|
||||
h.Cursor.ResetSelection()
|
||||
h.freshClip = true
|
||||
|
@ -1147,7 +1139,10 @@ func (h *BufPane) MoveLinesDown() bool {
|
|||
// Paste whatever is in the system clipboard into the buffer
|
||||
// Delete and paste if the user has a selection
|
||||
func (h *BufPane) Paste() bool {
|
||||
clip, _ := clipboard.ReadAll("clipboard")
|
||||
clip, err := clipboard.Read(clipboard.ClipboardReg)
|
||||
if err != nil {
|
||||
InfoBar.Error(err)
|
||||
}
|
||||
h.paste(clip)
|
||||
h.Relocate()
|
||||
return true
|
||||
|
@ -1155,7 +1150,10 @@ func (h *BufPane) Paste() bool {
|
|||
|
||||
// PastePrimary pastes from the primary clipboard (only use on linux)
|
||||
func (h *BufPane) PastePrimary() bool {
|
||||
clip, _ := clipboard.ReadAll("primary")
|
||||
clip, err := clipboard.Read(clipboard.PrimaryReg)
|
||||
if err != nil {
|
||||
InfoBar.Error(err)
|
||||
}
|
||||
h.paste(clip)
|
||||
h.Relocate()
|
||||
return true
|
||||
|
@ -1177,11 +1175,7 @@ func (h *BufPane) paste(clip string) {
|
|||
h.Buf.Insert(h.Cursor.Loc, clip)
|
||||
// h.Cursor.Loc = h.Cursor.Loc.Move(Count(clip), h.Buf)
|
||||
h.freshClip = false
|
||||
if clipboard.Unsupported {
|
||||
InfoBar.Message("Pasted clipboard (install xclip for external clipboard)")
|
||||
} else {
|
||||
InfoBar.Message("Pasted clipboard")
|
||||
}
|
||||
InfoBar.Message("Pasted clipboard")
|
||||
}
|
||||
|
||||
// JumpToMatchingBrace moves the cursor to the matching brace if it is
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
|
||||
lua "github.com/yuin/gopher-lua"
|
||||
"github.com/zyedidia/micro/v2/internal/buffer"
|
||||
"github.com/zyedidia/micro/v2/internal/clipboard"
|
||||
"github.com/zyedidia/micro/v2/internal/config"
|
||||
"github.com/zyedidia/micro/v2/internal/display"
|
||||
ulua "github.com/zyedidia/micro/v2/internal/lua"
|
||||
|
@ -360,7 +361,7 @@ func (h *BufPane) HandleEvent(event tcell.Event) {
|
|||
// h.Cursor.SetSelectionEnd(h.Cursor.Loc)
|
||||
// }
|
||||
if h.Cursor.HasSelection() {
|
||||
h.Cursor.CopySelection("primary")
|
||||
h.Cursor.CopySelection(clipboard.PrimaryReg)
|
||||
}
|
||||
h.mouseReleased = true
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import (
|
|||
|
||||
shellquote "github.com/kballard/go-shellquote"
|
||||
"github.com/zyedidia/micro/v2/internal/buffer"
|
||||
"github.com/zyedidia/micro/v2/internal/clipboard"
|
||||
"github.com/zyedidia/micro/v2/internal/config"
|
||||
"github.com/zyedidia/micro/v2/internal/screen"
|
||||
"github.com/zyedidia/micro/v2/internal/shell"
|
||||
|
@ -505,6 +506,12 @@ func SetGlobalOptionNative(option string, nativeValue interface{}) error {
|
|||
}
|
||||
} else if option == "paste" {
|
||||
screen.Screen.SetPaste(nativeValue.(bool))
|
||||
} else if option == "clipboard" {
|
||||
m := clipboard.SetMethod(nativeValue.(string))
|
||||
err := clipboard.Initialize(m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
for _, pl := range config.Plugins {
|
||||
if option == pl.Name {
|
||||
|
|
|
@ -186,6 +186,16 @@ func OptionValueComplete(b *buffer.Buffer) ([]string, []string) {
|
|||
if strings.HasPrefix("doas", input) {
|
||||
suggestions = append(suggestions, "doas")
|
||||
}
|
||||
case "clipboard":
|
||||
if strings.HasPrefix("external", input) {
|
||||
suggestions = append(suggestions, "external")
|
||||
}
|
||||
if strings.HasPrefix("internal", input) {
|
||||
suggestions = append(suggestions, "internal")
|
||||
}
|
||||
if strings.HasPrefix("terminal", input) {
|
||||
suggestions = append(suggestions, "terminal")
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Strings(suggestions)
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"errors"
|
||||
"runtime"
|
||||
|
||||
"github.com/zyedidia/clipboard"
|
||||
"github.com/zyedidia/micro/v2/internal/clipboard"
|
||||
"github.com/zyedidia/micro/v2/internal/display"
|
||||
"github.com/zyedidia/micro/v2/internal/screen"
|
||||
"github.com/zyedidia/micro/v2/internal/shell"
|
||||
|
@ -90,7 +90,7 @@ func (t *TermPane) HandleEvent(event tcell.Event) {
|
|||
}
|
||||
}
|
||||
if e.Key() == tcell.KeyCtrlC && t.HasSelection() {
|
||||
clipboard.WriteAll(t.GetSelection(t.GetView().Width), "clipboard")
|
||||
clipboard.Write(t.GetSelection(t.GetView().Width), clipboard.ClipboardReg)
|
||||
InfoBar.Message("Copied selection to clipboard")
|
||||
} else if t.Status != shell.TTDone {
|
||||
t.WriteString(event.EscSeq())
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package buffer
|
||||
|
||||
import (
|
||||
"github.com/zyedidia/clipboard"
|
||||
"github.com/zyedidia/micro/v2/internal/clipboard"
|
||||
"github.com/zyedidia/micro/v2/internal/util"
|
||||
)
|
||||
|
||||
|
@ -125,10 +125,10 @@ func (c *Cursor) End() {
|
|||
|
||||
// CopySelection copies the user's selection to either "primary"
|
||||
// or "clipboard"
|
||||
func (c *Cursor) CopySelection(target string) {
|
||||
func (c *Cursor) CopySelection(target clipboard.Register) {
|
||||
if c.HasSelection() {
|
||||
if target != "primary" || c.buf.Settings["useprimary"].(bool) {
|
||||
clipboard.WriteAll(string(c.GetSelection()), target)
|
||||
if target != clipboard.PrimaryReg || c.buf.Settings["useprimary"].(bool) {
|
||||
clipboard.Write(string(c.GetSelection()), target)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
151
internal/clipboard/clipboard.go
Normal file
151
internal/clipboard/clipboard.go
Normal file
|
@ -0,0 +1,151 @@
|
|||
package clipboard
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/zyedidia/clipboard"
|
||||
)
|
||||
|
||||
type Method int
|
||||
|
||||
const (
|
||||
// External relies on external tools for accessing the clipboard
|
||||
// These include xclip, xsel, wl-clipboard for linux, pbcopy/pbpaste on Mac,
|
||||
// and Syscalls on Windows.
|
||||
External Method = iota
|
||||
// Terminal uses the terminal to manage the clipboard via OSC 52. Many
|
||||
// terminals do not support OSC 52, in which case this method won't work.
|
||||
Terminal
|
||||
// Internal just manages the clipboard with an internal buffer and doesn't
|
||||
// attempt to interface with the system clipboard
|
||||
Internal
|
||||
)
|
||||
|
||||
// CurrentMethod is the method used to store clipboard information
|
||||
var CurrentMethod Method = Internal
|
||||
|
||||
// A Register is a buffer used to store text. The system clipboard has the 'clipboard'
|
||||
// and 'primary' (linux-only) registers, but other registers may be used internal to micro.
|
||||
type Register int
|
||||
|
||||
const (
|
||||
// ClipboardReg is the main system clipboard
|
||||
ClipboardReg Register = -1
|
||||
// PrimaryReg is the system primary clipboard (linux only)
|
||||
PrimaryReg = -2
|
||||
)
|
||||
|
||||
// Initialize attempts to initialize the clipboard using the given method
|
||||
func Initialize(m Method) error {
|
||||
var err error
|
||||
switch m {
|
||||
case External:
|
||||
err = clipboard.Initialize()
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// SetMethod changes the clipboard access method
|
||||
func SetMethod(m string) Method {
|
||||
switch m {
|
||||
case "internal":
|
||||
CurrentMethod = Internal
|
||||
case "external":
|
||||
CurrentMethod = External
|
||||
case "terminal":
|
||||
CurrentMethod = Terminal
|
||||
}
|
||||
return CurrentMethod
|
||||
}
|
||||
|
||||
// Read reads from a clipboard register
|
||||
func Read(r Register) (string, error) {
|
||||
return read(r, CurrentMethod)
|
||||
}
|
||||
|
||||
// Write writes text to a clipboard register
|
||||
func Write(text string, r Register) error {
|
||||
return write(text, r, CurrentMethod)
|
||||
}
|
||||
|
||||
// ReadMulti reads text from a clipboard register for a certain multi-cursor
|
||||
func ReadMulti(r Register, num int) (string, error) {
|
||||
s := multi.getText(r, num)
|
||||
return s, nil
|
||||
}
|
||||
|
||||
// WriteMulti writes text to a clipboard register for a certain multi-cursor
|
||||
func WriteMulti(text string, r Register, num int) error {
|
||||
return writeMulti(text, r, num, CurrentMethod)
|
||||
}
|
||||
|
||||
// ValidMulti checks if the internal multi-clipboard is valid and up-to-date
|
||||
// with the system clipboard
|
||||
func ValidMulti(r Register, ncursors int) bool {
|
||||
clip, err := Read(r)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return multi.isValid(r, ncursors, clip)
|
||||
}
|
||||
|
||||
func writeMulti(text string, r Register, num int, m Method) error {
|
||||
multi.writeText(text, r, num)
|
||||
return write(multi.getAllText(r), r, m)
|
||||
}
|
||||
|
||||
func read(r Register, m Method) (string, error) {
|
||||
switch m {
|
||||
case External:
|
||||
switch r {
|
||||
case ClipboardReg:
|
||||
return clipboard.ReadAll("clipboard")
|
||||
case PrimaryReg:
|
||||
return clipboard.ReadAll("primary")
|
||||
default:
|
||||
return internal.read(r), nil
|
||||
}
|
||||
case Internal:
|
||||
return internal.read(r), nil
|
||||
case Terminal:
|
||||
switch r {
|
||||
case ClipboardReg:
|
||||
// terminal paste works by sending an esc sequence to the
|
||||
// terminal to trigger a paste event
|
||||
err := terminal.read("clipboard")
|
||||
return "", err
|
||||
case PrimaryReg:
|
||||
err := terminal.read("primary")
|
||||
return "", err
|
||||
default:
|
||||
return internal.read(r), nil
|
||||
}
|
||||
}
|
||||
return "", errors.New("Invalid clipboard method")
|
||||
}
|
||||
|
||||
func write(text string, r Register, m Method) error {
|
||||
switch m {
|
||||
case External:
|
||||
switch r {
|
||||
case ClipboardReg:
|
||||
return clipboard.WriteAll(text, "clipboard")
|
||||
case PrimaryReg:
|
||||
return clipboard.WriteAll(text, "primary")
|
||||
default:
|
||||
internal.write(text, r)
|
||||
}
|
||||
case Internal:
|
||||
internal.write(text, r)
|
||||
case Terminal:
|
||||
switch r {
|
||||
case ClipboardReg:
|
||||
return terminal.write(text, "c")
|
||||
case PrimaryReg:
|
||||
return terminal.write(text, "p")
|
||||
default:
|
||||
internal.write(text, r)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
17
internal/clipboard/internal.go
Normal file
17
internal/clipboard/internal.go
Normal file
|
@ -0,0 +1,17 @@
|
|||
package clipboard
|
||||
|
||||
type internalClipboard map[Register]string
|
||||
|
||||
var internal internalClipboard
|
||||
|
||||
func init() {
|
||||
internal = make(internalClipboard)
|
||||
}
|
||||
|
||||
func (c internalClipboard) read(r Register) string {
|
||||
return c[r]
|
||||
}
|
||||
|
||||
func (c internalClipboard) write(text string, r Register) {
|
||||
c[r] = text
|
||||
}
|
66
internal/clipboard/multi.go
Normal file
66
internal/clipboard/multi.go
Normal file
|
@ -0,0 +1,66 @@
|
|||
package clipboard
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"hash/fnv"
|
||||
)
|
||||
|
||||
// For storing multi cursor clipboard contents
|
||||
type multiClipboard map[Register][]string
|
||||
|
||||
var multi multiClipboard
|
||||
|
||||
func (c multiClipboard) getAllText(r Register) string {
|
||||
content := c[r]
|
||||
if content == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
buf := &bytes.Buffer{}
|
||||
for _, s := range content {
|
||||
buf.WriteString(s)
|
||||
buf.WriteByte('\n')
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
func (c multiClipboard) getText(r Register, num int) string {
|
||||
content := c[r]
|
||||
if content == nil || len(content) <= num {
|
||||
return ""
|
||||
}
|
||||
|
||||
return content[num]
|
||||
}
|
||||
|
||||
func hash(s string) uint32 {
|
||||
h := fnv.New32a()
|
||||
h.Write([]byte(s))
|
||||
return h.Sum32()
|
||||
}
|
||||
|
||||
// isValid checks if the text stored in this multi-clipboard is the same as the
|
||||
// text stored in the system clipboard (provided as an argument), and therefore
|
||||
// if it is safe to use the multi-clipboard for pasting instead of the system
|
||||
// clipboard.
|
||||
func (c multiClipboard) isValid(r Register, ncursors int, clipboard string) bool {
|
||||
content := c[r]
|
||||
if content == nil || len(content) != ncursors {
|
||||
return false
|
||||
}
|
||||
|
||||
return hash(clipboard) == hash(c.getAllText(r))
|
||||
}
|
||||
|
||||
func (c multiClipboard) writeText(text string, r Register, num int) {
|
||||
content := c[r]
|
||||
if content == nil || num >= cap(content) {
|
||||
content = make([]string, num+1, num+1)
|
||||
}
|
||||
|
||||
content[num] = text
|
||||
}
|
||||
|
||||
func init() {
|
||||
multi = make(multiClipboard)
|
||||
}
|
15
internal/clipboard/terminal.go
Normal file
15
internal/clipboard/terminal.go
Normal file
|
@ -0,0 +1,15 @@
|
|||
package clipboard
|
||||
|
||||
import "github.com/zyedidia/micro/v2/internal/screen"
|
||||
|
||||
type terminalClipboard struct{}
|
||||
|
||||
var terminal terminalClipboard
|
||||
|
||||
func (t terminalClipboard) read(reg string) error {
|
||||
return screen.Screen.GetClipboard(reg)
|
||||
}
|
||||
|
||||
func (t terminalClipboard) write(text, reg string) error {
|
||||
return screen.Screen.SetClipboard(text, reg)
|
||||
}
|
|
@ -43,6 +43,7 @@ func init() {
|
|||
// Options with validators
|
||||
var optionValidators = map[string]optionValidator{
|
||||
"autosave": validateNonNegativeValue,
|
||||
"clipboard": validateClipboard,
|
||||
"tabsize": validatePositiveValue,
|
||||
"scrollmargin": validateNonNegativeValue,
|
||||
"scrollspeed": validateNonNegativeValue,
|
||||
|
@ -322,6 +323,7 @@ func DefaultCommonSettings() map[string]interface{} {
|
|||
// default values
|
||||
var DefaultGlobalOnlySettings = map[string]interface{}{
|
||||
"autosave": float64(0),
|
||||
"clipboard": "external",
|
||||
"colorscheme": "default",
|
||||
"divchars": "|-",
|
||||
"divreverse": true,
|
||||
|
@ -450,6 +452,22 @@ func validateColorscheme(option string, value interface{}) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func validateClipboard(option string, value interface{}) error {
|
||||
val, ok := value.(string)
|
||||
|
||||
if !ok {
|
||||
return errors.New("Expected string type for clipboard")
|
||||
}
|
||||
|
||||
switch val {
|
||||
case "internal", "external", "terminal":
|
||||
default:
|
||||
return errors.New(option + " must be 'internal', 'external', or 'terminal'")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateLineEnding(option string, value interface{}) error {
|
||||
endingType, ok := value.(string)
|
||||
|
||||
|
|
|
@ -4,8 +4,51 @@ because there are multiple methods. This help document will explain
|
|||
the various methods for copying and pasting, how they work,
|
||||
and the best methods for doing so over SSH.
|
||||
|
||||
# OSC 52 (terminal clipboard)
|
||||
|
||||
If possible, setting the `clipboard` option to `terminal` will give
|
||||
best results because it will work over SSH and locally. However, there
|
||||
is limited support among terminal emulators for the terminal clipboard
|
||||
(which uses the OSC 52 protocol to communicate clipboard contents).
|
||||
Here is a list of terminal emulators and their status:
|
||||
|
||||
* Kitty: supported, but only writing is enabled by default. To enable
|
||||
reading, add `read-primary` and `read-clipboard` to the
|
||||
`clipboard_control` option.
|
||||
|
||||
* iTerm2: supported, but must be enabled in
|
||||
`Preferences->General-> Selection->Applications in terminal may access clipboard`.
|
||||
|
||||
* `st`: supported.
|
||||
|
||||
* `rxvt-unicode`: not natively supported, but there is a Perl extension
|
||||
[here](http://anti.teamidiot.de/static/nei/*/Code/urxvt/).
|
||||
|
||||
* `xterm`: supported, but disabled by default. It can be enabled by putting
|
||||
the following in `.Xresources` or `.Xdefaults`:
|
||||
`XTerm*disallowedWindowOps: 20,21,SetXprop`.
|
||||
|
||||
* `gnome-terminal`: does not support OSC 52.
|
||||
|
||||
**Summary:** If you want copy and paste to work over SSH, then you
|
||||
should set `clipboard` to `terminal`, and make sure your terminal
|
||||
supports OSC 52.
|
||||
|
||||
# Pasting
|
||||
|
||||
## Recommendations (TL;DR)
|
||||
|
||||
The recommended method of pasting is the following:
|
||||
|
||||
* If you are not working over SSH, use the micro keybinding (Ctrl-v
|
||||
by default) to perform pastes. If on Linux, install `xclip` or
|
||||
`xsel` beforehand.
|
||||
|
||||
* If you are working over SSH, use the terminal keybinding
|
||||
(Ctrl-Shift-v or Command-v) to perform pastes. If your terminal
|
||||
does not support bracketed paste, when performing a paste first
|
||||
enable the `paste` option, and when finished disable the option.
|
||||
|
||||
## Micro paste events
|
||||
|
||||
Micro is an application that runs within the terminal. This means
|
||||
|
@ -56,20 +99,23 @@ machine's clipboard. On the other hand, the terminal keybinding
|
|||
for paste will access your local clipboard and send the text over
|
||||
the network as a paste event, which is what you want.
|
||||
|
||||
## Recommendations
|
||||
# Copying
|
||||
|
||||
The recommended method of pasting is the following:
|
||||
# Recommendations (TL;DR)
|
||||
|
||||
* If you are not working over SSH, use the micro keybinding (Ctrl-v
|
||||
by default) to perform pastes. If on Linux, install `xclip` or
|
||||
`xsel` beforehand.
|
||||
The recommended method of copying is the following:
|
||||
|
||||
* If you are not working over SSH, use the micro keybinding (Ctrl-c by
|
||||
default) to perform copies. If on Linux, install `xclip` or `xsel`
|
||||
beforehand.
|
||||
|
||||
* If you are working over SSH, use the terminal keybinding
|
||||
(Ctrl-Shift-v or Command-v) to perform pastes. If your terminal
|
||||
does not support bracketed paste, when performing a paste first
|
||||
enable the `paste` option, and when finished disable the option.
|
||||
|
||||
# Copying
|
||||
(Ctrl-Shift-c or Command-c) to perform copies. You must first disable
|
||||
the `mouse` option to perform a terminal selection, and you may wish
|
||||
to disable line numbers and diff indicators (`ruler` and `diffgutter`
|
||||
options) and close other splits. This method will only be able to copy
|
||||
characters that are displayed on the screen (you will not be able to
|
||||
copy more than one page's worth of characters).
|
||||
|
||||
Copying follows a similar discussion to the one above about pasting.
|
||||
The primary difference is before performing a copy, the application
|
||||
|
@ -92,19 +138,3 @@ means that for copying multiple lines using the terminal selection, you
|
|||
should first disable line numbers and diff indicators (turn off the `ruler`
|
||||
and `diffgutter` options), otherwise they might be part of your selection
|
||||
and copied.
|
||||
|
||||
## Recommendations
|
||||
|
||||
The recommended method of copying is the following:
|
||||
|
||||
* If you are not working over SSH, use the micro keybinding (Ctrl-c by
|
||||
default) to perform copies. If on Linux, install `xclip` or `xsel`
|
||||
beforehand.
|
||||
|
||||
* If you are working over SSH, use the terminal keybinding
|
||||
(Ctrl-Shift-c or Command-c) to perform copies. You must first disable
|
||||
the `mouse` option to perform a terminal selection, and you may wish
|
||||
to disable line numbers and diff indicators (`ruler` and `diffgutter`
|
||||
options) and close other splits. This method will only be able to copy
|
||||
characters that are displayed on the screen (you will not be able to
|
||||
copy more than one page's worth of characters).
|
||||
|
|
|
@ -54,6 +54,25 @@ Here are the available options:
|
|||
|
||||
default value: `false`
|
||||
|
||||
* `clipboard`: specifies how micro should access the system clipboard.
|
||||
Possible values are:
|
||||
* `external`: accesses clipboard via an external tool, such as xclip/xsel
|
||||
or wl-clipboard on Linux, pbcopy/pbpaste on MacOS, and system calls on
|
||||
Windows. On Linux, if you do not have one of the tools installed, or if
|
||||
they are not working, micro will throw an error and use an internal
|
||||
clipboard.
|
||||
* `terminal`: accesses the clipboard via your terminal emulator. Note that
|
||||
there is limited support among terminal emulators for this feature
|
||||
(called OSC 52). Terminals that are known to work are Kitty (enable
|
||||
reading with `clipboard_control` setting), iTerm2 (enable in prefs),
|
||||
st, rxvt-unicode and xterm if enabled (see `> help copypaste` for
|
||||
details). Note that Gnome-terminal does not support this feature. With
|
||||
this setting, copy-paste **will** work over ssh. See `> help copypaste`
|
||||
for details.
|
||||
* `internal`: micro will use an internal clipboard.
|
||||
|
||||
default value: `external`
|
||||
|
||||
* `colorcolumn`: if this is not set to 0, it will display a column at the
|
||||
specified column. This is useful if you want column 80 to be highlighted
|
||||
special for example.
|
||||
|
|
Loading…
Reference in a new issue