зеркало из https://github.com/mislav/hub.git
Copy to clipboard for `create`, `issue`, `pull-request`, `release`
Also add `--browse` functionality to `create` and `release` for parity with `issue` and `pull-request`.
This commit is contained in:
Родитель
6fdc4c1a88
Коммит
f7c1105df3
|
@ -13,7 +13,7 @@ import (
|
|||
|
||||
var cmdCreate = &Command{
|
||||
Run: create,
|
||||
Usage: "create [-p] [-d <DESCRIPTION>] [-h <HOMEPAGE>] [[<ORGANIZATION>/]<NAME>]",
|
||||
Usage: "create [-poc] [-d <DESCRIPTION>] [-h <HOMEPAGE>] [[<ORGANIZATION>/]<NAME>]",
|
||||
Long: `Create a new repository on GitHub and add a git remote for it.
|
||||
|
||||
## Options:
|
||||
|
@ -26,6 +26,12 @@ var cmdCreate = &Command{
|
|||
-h <HOMEPAGE>
|
||||
Use this text as the URL of the GitHub repository.
|
||||
|
||||
-o, --browse
|
||||
Open the new repository in a web browser.
|
||||
|
||||
-c, --copy
|
||||
Put the URL of the new repository to clipboard instead of printing it.
|
||||
|
||||
[<ORGANIZATION>/]<NAME>
|
||||
The name for the repository on GitHub (default: name of the current working
|
||||
directory).
|
||||
|
@ -48,12 +54,18 @@ hub-init(1), hub(1)
|
|||
}
|
||||
|
||||
var (
|
||||
flagCreatePrivate bool
|
||||
flagCreateDescription, flagCreateHomepage string
|
||||
flagCreatePrivate,
|
||||
flagCreateBrowse,
|
||||
flagCreateCopy bool
|
||||
|
||||
flagCreateDescription,
|
||||
flagCreateHomepage string
|
||||
)
|
||||
|
||||
func init() {
|
||||
cmdCreate.Flag.BoolVarP(&flagCreatePrivate, "private", "p", false, "PRIVATE")
|
||||
cmdCreate.Flag.BoolVarP(&flagCreateBrowse, "browse", "o", false, "BROWSE")
|
||||
cmdCreate.Flag.BoolVarP(&flagCreateCopy, "copy", "c", false, "COPY")
|
||||
cmdCreate.Flag.StringVarP(&flagCreateDescription, "description", "d", "", "DESCRIPTION")
|
||||
cmdCreate.Flag.StringVarP(&flagCreateHomepage, "homepage", "h", "", "HOMEPAGE")
|
||||
|
||||
|
@ -118,5 +130,5 @@ func create(command *Command, args *Args) {
|
|||
|
||||
webUrl := project.WebURL("", "", "")
|
||||
args.NoForward()
|
||||
printBrowseOrCopy(args, webUrl, false, false)
|
||||
printBrowseOrCopy(args, webUrl, flagCreateBrowse, flagCreateCopy)
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ var (
|
|||
Run: listIssues,
|
||||
Usage: `
|
||||
issue [-a <ASSIGNEE>] [-c <CREATOR>] [-@ <USER] [-s <STATE>] [-f <FORMAT>] [-M <MILESTONE>] [-l <LABELS>] [-t <TIME>]
|
||||
issue create [-o] [-m <MESSAGE>|-F <FILE>] [-a <USERS>] [-M <MILESTONE>] [-l <LABELS>]
|
||||
issue create [-oc] [-m <MESSAGE>|-F <FILE>] [-a <USERS>] [-M <MILESTONE>] [-l <LABELS>]
|
||||
`,
|
||||
Long: `Manage GitHub issues for the current project.
|
||||
|
||||
|
@ -109,6 +109,9 @@ With no arguments, show a list of open issues.
|
|||
-o, --browse
|
||||
Open the new issue in a web browser.
|
||||
|
||||
-c, --copy
|
||||
Put the URL of the new issue to clipboard instead of printing it.
|
||||
|
||||
-M, --milestone <ID>
|
||||
Display only issues for a GitHub milestone with id <ID>.
|
||||
|
||||
|
@ -143,6 +146,7 @@ With no arguments, show a list of open issues.
|
|||
flagIssueFile string
|
||||
|
||||
flagIssueEdit,
|
||||
flagIssueCopy,
|
||||
flagIssueBrowse bool
|
||||
|
||||
flagIssueMilestone uint64
|
||||
|
@ -158,6 +162,7 @@ func init() {
|
|||
cmdCreateIssue.Flag.VarP(&flagIssueLabels, "label", "l", "LABEL")
|
||||
cmdCreateIssue.Flag.VarP(&flagIssueAssignees, "assign", "a", "ASSIGNEE")
|
||||
cmdCreateIssue.Flag.BoolVarP(&flagIssueBrowse, "browse", "o", false, "BROWSE")
|
||||
cmdCreateIssue.Flag.BoolVarP(&flagIssueCopy, "copy", "c", false, "COPY")
|
||||
cmdCreateIssue.Flag.BoolVarP(&flagIssueEdit, "edit", "e", false, "EDIT")
|
||||
|
||||
cmdIssue.Flag.StringVarP(&flagIssueAssignee, "assignee", "a", "", "ASSIGNEE")
|
||||
|
@ -393,6 +398,6 @@ func createIssue(cmd *Command, args *Args) {
|
|||
issue, err := gh.CreateIssue(project, params)
|
||||
utils.Check(err)
|
||||
|
||||
printBrowseOrCopy(args, issue.HtmlUrl, flagIssueBrowse, false)
|
||||
printBrowseOrCopy(args, issue.HtmlUrl, flagIssueBrowse, flagIssueCopy)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ import (
|
|||
var cmdPullRequest = &Command{
|
||||
Run: pullRequest,
|
||||
Usage: `
|
||||
pull-request [-fo] [-b <BASE>] [-h <HEAD>] [-a <USERS>] [-M <MILESTONE>] [-l <LABELS>]
|
||||
pull-request [-foc] [-b <BASE>] [-h <HEAD>] [-a <USERS>] [-M <MILESTONE>] [-l <LABELS>]
|
||||
pull-request -m <MESSAGE>
|
||||
pull-request -F <FILE> [--edit]
|
||||
pull-request -i <ISSUE>
|
||||
|
@ -42,6 +42,9 @@ pull-request -i <ISSUE>
|
|||
-o, --browse
|
||||
Open the new pull request in a web browser.
|
||||
|
||||
-c, --copy
|
||||
Put the URL of the new pull request to clipboard instead of printing it.
|
||||
|
||||
-b, --base <BASE>
|
||||
The base branch in "[OWNER:]BRANCH" format. Defaults to the default branch
|
||||
(usually "master").
|
||||
|
@ -72,6 +75,7 @@ var (
|
|||
flagPullRequestFile string
|
||||
|
||||
flagPullRequestBrowse,
|
||||
flagPullRequestCopy,
|
||||
flagPullRequestEdit,
|
||||
flagPullRequestForce bool
|
||||
|
||||
|
@ -86,6 +90,7 @@ func init() {
|
|||
cmdPullRequest.Flag.StringVarP(&flagPullRequestHead, "head", "h", "", "HEAD")
|
||||
cmdPullRequest.Flag.StringVarP(&flagPullRequestIssue, "issue", "i", "", "ISSUE")
|
||||
cmdPullRequest.Flag.BoolVarP(&flagPullRequestBrowse, "browse", "o", false, "BROWSE")
|
||||
cmdPullRequest.Flag.BoolVarP(&flagPullRequestCopy, "copy", "c", false, "COPY")
|
||||
cmdPullRequest.Flag.StringVarP(&flagPullRequestMessage, "message", "m", "", "MESSAGE")
|
||||
cmdPullRequest.Flag.BoolVarP(&flagPullRequestEdit, "edit", "e", false, "EDIT")
|
||||
cmdPullRequest.Flag.BoolVarP(&flagPullRequestForce, "force", "f", false, "FORCE")
|
||||
|
@ -268,7 +273,7 @@ func pullRequest(cmd *Command, args *Args) {
|
|||
}
|
||||
|
||||
args.NoForward()
|
||||
printBrowseOrCopy(args, pullRequestURL, flagPullRequestBrowse, false)
|
||||
printBrowseOrCopy(args, pullRequestURL, flagPullRequestBrowse, flagPullRequestCopy)
|
||||
}
|
||||
|
||||
func createPullRequestMessage(base, head, fullBase, fullHead string) (string, error) {
|
||||
|
|
|
@ -19,7 +19,7 @@ var (
|
|||
Usage: `
|
||||
release [--include-drafts]
|
||||
release show <TAG>
|
||||
release create [-dp] [-a <FILE>] [-m <MESSAGE>|-F <FILE>] [-t <TARGET>] <TAG>
|
||||
release create [-dpoc] [-a <FILE>] [-m <MESSAGE>|-F <FILE>] [-t <TARGET>] <TAG>
|
||||
release edit [<options>] <TAG>
|
||||
`,
|
||||
Long: `Manage GitHub releases.
|
||||
|
@ -72,6 +72,12 @@ With '--include-drafts', include draft releases in the listing.
|
|||
-e, --edit
|
||||
Further edit the contents of <FILE> in a text editor before submitting.
|
||||
|
||||
-o, --browse
|
||||
Open the new release in a web browser.
|
||||
|
||||
-c, --copy
|
||||
Put the URL of the new release to clipboard instead of printing it.
|
||||
|
||||
-t, --commitish <TARGET>
|
||||
A commit SHA or branch name to attach the release to, only used if <TAG>
|
||||
doesn't already exist (default: main branch).
|
||||
|
@ -109,6 +115,8 @@ hub(1), git-tag(1)
|
|||
flagReleaseShowDownloads,
|
||||
flagReleaseDraft,
|
||||
flagReleaseEdit,
|
||||
flagReleaseBrowse,
|
||||
flagReleaseCopy,
|
||||
flagReleasePrerelease bool
|
||||
|
||||
flagReleaseMessage,
|
||||
|
@ -126,6 +134,8 @@ func init() {
|
|||
cmdCreateRelease.Flag.BoolVarP(&flagReleaseEdit, "edit", "e", false, "EDIT")
|
||||
cmdCreateRelease.Flag.BoolVarP(&flagReleaseDraft, "draft", "d", false, "DRAFT")
|
||||
cmdCreateRelease.Flag.BoolVarP(&flagReleasePrerelease, "prerelease", "p", false, "PRERELEASE")
|
||||
cmdCreateRelease.Flag.BoolVarP(&flagReleaseBrowse, "browse", "o", false, "BROWSE")
|
||||
cmdCreateRelease.Flag.BoolVarP(&flagReleaseCopy, "copy", "c", false, "COPY")
|
||||
cmdCreateRelease.Flag.VarP(&flagReleaseAssets, "attach", "a", "ATTACH_ASSETS")
|
||||
cmdCreateRelease.Flag.StringVarP(&flagReleaseMessage, "message", "m", "", "MESSAGE")
|
||||
cmdCreateRelease.Flag.StringVarP(&flagReleaseFile, "file", "F", "", "FILE")
|
||||
|
@ -316,7 +326,7 @@ func createRelease(cmd *Command, args *Args) {
|
|||
release, err = gh.CreateRelease(project, params)
|
||||
utils.Check(err)
|
||||
|
||||
printBrowseOrCopy(args, release.HtmlUrl, false, false)
|
||||
printBrowseOrCopy(args, release.HtmlUrl, flagReleaseBrowse, flagReleaseCopy)
|
||||
}
|
||||
|
||||
if editor != nil {
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/atotto/clipboard"
|
||||
"github.com/github/hub/git"
|
||||
"github.com/github/hub/github"
|
||||
"github.com/github/hub/ui"
|
||||
|
@ -137,7 +138,9 @@ func runInLocalRepo(fn func(localRepo *github.GitHubRepo, project *github.Projec
|
|||
|
||||
func printBrowseOrCopy(args *Args, msg string, openBrowser bool, performCopy bool) {
|
||||
if performCopy {
|
||||
// TODO
|
||||
if err := clipboard.WriteAll(msg); err != nil {
|
||||
ui.Errorf("Error copying %s to clipboard:\n%s\n", msg, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
if openBrowser {
|
||||
|
|
|
@ -129,6 +129,17 @@ Feature: hub create
|
|||
Then the url for "origin" should be "git@github.com:Mooslav/myconfig.git"
|
||||
And the output should contain exactly "https://github.com/Mooslav/myconfig\n"
|
||||
|
||||
Scenario: Open new repository in web browser
|
||||
Given the GitHub API server:
|
||||
"""
|
||||
post('/user/repos') {
|
||||
json :full_name => 'Mooslav/myconfig'
|
||||
}
|
||||
"""
|
||||
When I successfully run `hub create -o`
|
||||
Then the output should contain exactly ""
|
||||
And "open https://github.com/Mooslav/myconfig" should be run
|
||||
|
||||
Scenario: Current directory contains spaces
|
||||
Given I am in "my dot files" git repo
|
||||
Given the GitHub API server:
|
||||
|
|
|
@ -237,6 +237,18 @@ MARKDOWN
|
|||
Attaching release asset `./hello-1.2.0.tar.gz'...\n
|
||||
"""
|
||||
|
||||
Scenario: Open new release in web browser
|
||||
Given the GitHub API server:
|
||||
"""
|
||||
post('/repos/mislav/will_paginate/releases') {
|
||||
status 201
|
||||
json :html_url => "https://github.com/mislav/will_paginate/releases/v1.2.0"
|
||||
}
|
||||
"""
|
||||
When I successfully run `hub release create -o -m hello v1.2.0`
|
||||
Then the output should contain exactly ""
|
||||
And "open https://github.com/mislav/will_paginate/releases/v1.2.0" should be run
|
||||
|
||||
Scenario: Edit existing release
|
||||
Given the GitHub API server:
|
||||
"""
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
Copyright (c) 2013 Ato Araki. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of @atotto. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@ -0,0 +1,50 @@
|
|||
[![Build Status](https://travis-ci.org/atotto/clipboard.svg?branch=master)](https://travis-ci.org/atotto/clipboard) [![Build Status](https://drone.io/github.com/atotto/clipboard/status.png)](https://drone.io/github.com/atotto/clipboard/latest)
|
||||
|
||||
[![GoDoc](https://godoc.org/github.com/atotto/clipboard?status.svg)](http://godoc.org/github.com/atotto/clipboard)
|
||||
|
||||
# Clipboard for Go
|
||||
|
||||
Provide copying and pasting to the Clipboard for Go.
|
||||
|
||||
Download shell commands at https://drone.io/github.com/atotto/clipboard/files
|
||||
|
||||
Build:
|
||||
|
||||
$ go get github.com/atotto/clipboard
|
||||
|
||||
Platforms:
|
||||
|
||||
* OSX
|
||||
* Windows 7 (probably work on other Windows)
|
||||
* Linux, Unix (requires 'xclip' or 'xsel' command to be installed)
|
||||
|
||||
|
||||
Document:
|
||||
|
||||
* http://godoc.org/github.com/atotto/clipboard
|
||||
|
||||
Notes:
|
||||
|
||||
* Text string only
|
||||
* UTF-8 text encoding only (no conversion)
|
||||
|
||||
TODO:
|
||||
|
||||
* Clipboard watcher(?)
|
||||
|
||||
## Commands:
|
||||
|
||||
paste shell command:
|
||||
|
||||
$ go get github.com/atotto/clipboard/cmd/gopaste
|
||||
$ # example:
|
||||
$ gopaste > document.txt
|
||||
|
||||
copy shell command:
|
||||
|
||||
$ go get github.com/atotto/clipboard/cmd/gocopy
|
||||
$ # example:
|
||||
$ cat document.txt | gocopy
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
// Copyright 2013 @atotto. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package clipboard read/write on clipboard
|
||||
package clipboard
|
||||
|
||||
import ()
|
||||
|
||||
// ReadAll read string from clipboard
|
||||
func ReadAll() (string, error) {
|
||||
return readAll()
|
||||
}
|
||||
|
||||
// WriteAll write string to clipboard
|
||||
func WriteAll(text string) error {
|
||||
return writeAll(text)
|
||||
}
|
||||
|
||||
// Unsupported might be set true during clipboard init, to help callers decide
|
||||
// whether or not to offer clipboard options.
|
||||
var Unsupported bool
|
|
@ -0,0 +1,52 @@
|
|||
// Copyright 2013 @atotto. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build darwin
|
||||
|
||||
package clipboard
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
var (
|
||||
pasteCmdArgs = "pbpaste"
|
||||
copyCmdArgs = "pbcopy"
|
||||
)
|
||||
|
||||
func getPasteCommand() *exec.Cmd {
|
||||
return exec.Command(pasteCmdArgs)
|
||||
}
|
||||
|
||||
func getCopyCommand() *exec.Cmd {
|
||||
return exec.Command(copyCmdArgs)
|
||||
}
|
||||
|
||||
func readAll() (string, error) {
|
||||
pasteCmd := getPasteCommand()
|
||||
out, err := pasteCmd.Output()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(out), nil
|
||||
}
|
||||
|
||||
func writeAll(text string) error {
|
||||
copyCmd := getCopyCommand()
|
||||
in, err := copyCmd.StdinPipe()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := copyCmd.Start(); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := in.Write([]byte(text)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := in.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
return copyCmd.Wait()
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
// Copyright 2013 @atotto. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build freebsd linux netbsd openbsd solaris
|
||||
|
||||
package clipboard
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
const (
|
||||
xsel = "xsel"
|
||||
xclip = "xclip"
|
||||
)
|
||||
|
||||
var (
|
||||
pasteCmdArgs []string
|
||||
copyCmdArgs []string
|
||||
|
||||
xselPasteArgs = []string{xsel, "--output", "--clipboard"}
|
||||
xselCopyArgs = []string{xsel, "--input", "--clipboard"}
|
||||
|
||||
xclipPasteArgs = []string{xclip, "-out", "-selection", "clipboard"}
|
||||
xclipCopyArgs = []string{xclip, "-in", "-selection", "clipboard"}
|
||||
|
||||
missingCommands = errors.New("No clipboard utilities available. Please install xsel or xclip.")
|
||||
)
|
||||
|
||||
func init() {
|
||||
pasteCmdArgs = xclipPasteArgs
|
||||
copyCmdArgs = xclipCopyArgs
|
||||
|
||||
if _, err := exec.LookPath(xclip); err == nil {
|
||||
return
|
||||
}
|
||||
|
||||
pasteCmdArgs = xselPasteArgs
|
||||
copyCmdArgs = xselCopyArgs
|
||||
|
||||
if _, err := exec.LookPath(xsel); err == nil {
|
||||
return
|
||||
}
|
||||
|
||||
Unsupported = true
|
||||
}
|
||||
|
||||
func getPasteCommand() *exec.Cmd {
|
||||
return exec.Command(pasteCmdArgs[0], pasteCmdArgs[1:]...)
|
||||
}
|
||||
|
||||
func getCopyCommand() *exec.Cmd {
|
||||
return exec.Command(copyCmdArgs[0], copyCmdArgs[1:]...)
|
||||
}
|
||||
|
||||
func readAll() (string, error) {
|
||||
if Unsupported {
|
||||
return "", missingCommands
|
||||
}
|
||||
pasteCmd := getPasteCommand()
|
||||
out, err := pasteCmd.Output()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(out), nil
|
||||
}
|
||||
|
||||
func writeAll(text string) error {
|
||||
if Unsupported {
|
||||
return missingCommands
|
||||
}
|
||||
copyCmd := getCopyCommand()
|
||||
in, err := copyCmd.StdinPipe()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := copyCmd.Start(); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := in.Write([]byte(text)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := in.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
return copyCmd.Wait()
|
||||
}
|
101
vendor/github.com/atotto/clipboard/clipboard_windows.go
сгенерированный
поставляемый
Normal file
101
vendor/github.com/atotto/clipboard/clipboard_windows.go
сгенерированный
поставляемый
Normal file
|
@ -0,0 +1,101 @@
|
|||
// Copyright 2013 @atotto. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build windows
|
||||
|
||||
package clipboard
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
cfUnicodetext = 13
|
||||
gmemFixed = 0x0000
|
||||
)
|
||||
|
||||
var (
|
||||
user32 = syscall.MustLoadDLL("user32")
|
||||
openClipboard = user32.MustFindProc("OpenClipboard")
|
||||
closeClipboard = user32.MustFindProc("CloseClipboard")
|
||||
emptyClipboard = user32.MustFindProc("EmptyClipboard")
|
||||
getClipboardData = user32.MustFindProc("GetClipboardData")
|
||||
setClipboardData = user32.MustFindProc("SetClipboardData")
|
||||
|
||||
kernel32 = syscall.NewLazyDLL("kernel32")
|
||||
globalAlloc = kernel32.NewProc("GlobalAlloc")
|
||||
globalFree = kernel32.NewProc("GlobalFree")
|
||||
globalLock = kernel32.NewProc("GlobalLock")
|
||||
globalUnlock = kernel32.NewProc("GlobalUnlock")
|
||||
lstrcpy = kernel32.NewProc("lstrcpyW")
|
||||
)
|
||||
|
||||
func readAll() (string, error) {
|
||||
r, _, err := openClipboard.Call(0)
|
||||
if r == 0 {
|
||||
return "", err
|
||||
}
|
||||
defer closeClipboard.Call()
|
||||
|
||||
h, _, err := getClipboardData.Call(cfUnicodetext)
|
||||
if r == 0 {
|
||||
return "", err
|
||||
}
|
||||
|
||||
l, _, err := globalLock.Call(h)
|
||||
if l == 0 {
|
||||
return "", err
|
||||
}
|
||||
|
||||
text := syscall.UTF16ToString((*[1 << 20]uint16)(unsafe.Pointer(l))[:])
|
||||
|
||||
r, _, err = globalUnlock.Call(h)
|
||||
if r == 0 {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return text, nil
|
||||
}
|
||||
|
||||
func writeAll(text string) error {
|
||||
r, _, err := openClipboard.Call(0)
|
||||
if r == 0 {
|
||||
return err
|
||||
}
|
||||
defer closeClipboard.Call()
|
||||
|
||||
r, _, err = emptyClipboard.Call(0)
|
||||
if r == 0 {
|
||||
return err
|
||||
}
|
||||
|
||||
data := syscall.StringToUTF16(text)
|
||||
|
||||
h, _, err := globalAlloc.Call(gmemFixed, uintptr(len(data)*int(unsafe.Sizeof(data[0]))))
|
||||
if h == 0 {
|
||||
return err
|
||||
}
|
||||
|
||||
l, _, err := globalLock.Call(h)
|
||||
if l == 0 {
|
||||
return err
|
||||
}
|
||||
|
||||
r, _, err = lstrcpy.Call(l, uintptr(unsafe.Pointer(&data[0])))
|
||||
if r == 0 {
|
||||
return err
|
||||
}
|
||||
|
||||
r, _, err = globalUnlock.Call(h)
|
||||
if r == 0 {
|
||||
return err
|
||||
}
|
||||
|
||||
r, _, err = setClipboardData.Call(cfUnicodetext, h)
|
||||
if r == 0 {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
Загрузка…
Ссылка в новой задаче