Goland 快捷鍵講解


原則

快捷鍵不能過多

快捷鍵不能過多,一個 ide 就有許多快捷鍵,再加上瀏覽器,終端等等,快捷鍵如此之多,而且快捷鍵與功能之間並沒有關系,也就是說,你只能靠大量練習形成肌肉記憶,這並不是一個高效的學習方式。

一般來說,對於一個應用來說,記憶 20,30 個都是很多的了,最主要的不是把快捷鍵記住,而是你要知道你在干什么,你要干什么。

不要只死記快捷鍵,要理解它的意義

比如我曾經無數次搜索 Goland 的快捷鍵表,可是最后記憶的還是那么幾個,幾乎沒有增加,像什么 alt+shift,實現接口的 ctrl+i ,我看見過許多次,可是我仍然無法記住。

現在看來,這種方式就是錯誤的,不應該去“記憶”,而是要先理解它是什么意義,然后在用的時候會想到有這么一個功能,然后再去用。

使用工具幫助記憶

自然我們會時常忘記對應的快捷鍵是什么,但這其實反而並不是太大的問題。為了解決這個問題,我們有兩個方法。一就是寫 cheat-list,要用的時候直接查,而就是使用搜索功能,直接搜索對應的快捷鍵。而在 Goland 中,搜索功能就是特殊的幾個快捷鍵,如搜索 action, file, type 等。

這里擴展一下 i3 桌面,也是這么個道理,把多余的畫面去掉,即可以強迫我們使用鍵盤,也能強迫我們使用搜索功能。無鼠標編程顯然效率是灰常高的,當然也比時常要移動手去使用鼠標要舒適,還有 b 格加成。然后同時使用搜索功能也有幾個好處。一是強化功能的印象,搜索時,其名字往往代表其功能,故在搜索時能表明知道自己在做什么,也能強化有這個功能的印象,許多功能並不是只有這個工具才有,這種強化思維也能遷移,會提高有意識提高效率的意識,會主動去尋找提高效率的方式,同時遷移工具時也會考慮這些。最后就是熟悉一下單詞,比如我現在已經能熟練拼寫 settings, plugins, keymap, background等等。。這能加大我們接觸英語的可能性,因為這是我們主動的,而不是被動的。

  • 不要大幅度的修改初始快捷鍵

自由度過高,大幅度的修改快捷鍵有一些壞處,如難以遷移,從遷移環境時比較麻煩,別人難以使用,有時會有牽一發而動全身的效果,改一個快捷鍵可能會造成后續大量的快捷鍵沖突,自定義的不符合人體工程學,上手成本過高等等。我曾經在 Goland 中使用 vim 插件,給 action 自定義了大量的快捷鍵,而且不同模式移動光標方法也不同,我使用的鍵盤也是可編程鍵盤,然后折騰了許久,最后對這一套我自己也不熟悉,編程效率直線下賤,而代碼卻未敲幾行,甚至我還嘗試過不同的鍵盤布局,最后我想到有時會使用其他環境而放棄了。總之,一切皆有度。

移動光標

基礎

上 下 左 右

移動到行首/尾

向上/下翻頁

這幾個都是非常高頻的鍵,但是如果是標准鍵位,使用這幾個鍵都有大幅度的手部移動,這是非常難受的。我使用的是 66 布局,可以硬件編程。在 Space 左邊有一個 fn 鍵,我的設置是

fn + h/j/k/l 左/下/上/右

fn + i/o home/end

fn + ; / page up/ page down

左手大拇指按住 fn,右書按字母,這樣不用移動手,習慣了后效率還是挺高的。

  • Ctrl+m

這也是一個常用的鍵,有時候我們的寫着寫着,光標就到屏幕底部了,繼續寫時觀看很不方便,這時我們就可以使用這個鍵,屏幕會滑動到光標所在處,即屏幕以光標為中心。

Ctrl+左/右 移動到上/下一個單詞

Ctrl+home/end 移動到文件首/尾處

Ctrl+上/下 屏幕滑動但光標不動

跳轉

  • ctrl+B

這是一個非常常用的鍵,使用這個會跳轉到變量的定義處,如我們要查看某個函數的源碼實現時,對着實例使用即可

  • 插件: acejump-lite

當我們要在屏幕上跳轉時,如光標在屏幕低,要跳轉到屏幕頂某處,就可以使用這個插件,我自定義為 fn+m, 然后輸入跳轉的目標字符

  • Ctrl+e

這是一個非常常用的鍵

當我們要跳轉到最近的文件時,可以使用這個鍵,然后移動到目標文件

當要跳轉到某個文件時,也可以輸入這個鍵,先使用這個鍵,然后輸入文件名即可,這個類似使用 Ctrl+shift+N 查找文件

當我們要進入一些彈窗時,如要進入 run 窗口, terminal 窗口,enven log 窗口時,或者一些插件的窗口,如 translate 插件的 word book (生詞本) 窗口,可以使用這個鍵再搜索名字

  • Ctrl+Shift+A

這也是一個非常常用的鍵,我們可以用這個鍵做許多事,這個鍵用來使用 action,action 是 goland 中許多操作都有的一個東西。

如我們要打開 設置,就可以使用鍵后,輸入 settings 即可

如我們要打開 插件,輸入 plugins, 要把主菜單關掉,可以輸入 main ,第一個就是,或者我們要刪除文件,可以對着文件輸入 delete, 要新建文件,可以輸入 go,要新建項目,可以輸入 project ,要 運行代碼,可以輸入 run 等等,總之這個鍵可以代替大多數需要移動鼠標才能做的,要達到無鼠標編程,這個鍵需要熟練使用。

  • Ctrl+ 2/3

在編程中,我們經常會遇到 error,waring 等,我們想要檢查文件有沒有這些時,就可以使用這個鍵,在 goland 中原來的鍵是 F2/shift+F2, 即查詢下/上一個 error,但是我鍵盤布局不方便,所以設置了一下

想提高程序健壯性,即檢查 error, waing 等時,就可以使用這個鍵,在 goland 中一般 error 是紅色下划線,警告是黃色下划線,還有其他的提示等,總之在提示處有值得改進的地方

想要快速跳轉到 error 處,有時候我們要修改 error 時,使用 光標移動顯然有些低效,這是我們可以直接用這個鍵,就可以直接跳轉到 error 處

  • ctrl+shfit

返回剛打開的 tab

enter 新建下一行並移動到下一行, 改變此行

ctrl+enter 拆分此行,鼠標不動,在行尾使用,可新建下一行並鼠標不動

shift+enter 新建下一行並移動到下一行(不改變此行)

ctrl+alt+enter 新建上一行並到上一行

Ctrl+N fing type

Ctrl+Shift+N 查找 file
Ctrl+Alt+Shift+N 查找 func

Ctrl+[ 跳轉到函數大括號開始

Ctrl+] 跳轉到函數大括號結束

提示

  • Ctrl+1 顯示 error
  • Ctrl+p 顯示參數 parameter info
  • Ctrl+Q show documentation, 用來顯示返回值比較方便

其他

  • fn+s

這三個設置為一個快捷鍵比較方便,我使用的是硬件編程,也可是試試 vim 插件,我還沒有找到其他方法能夠這樣設置

Ctrl+Alt+L 格式化代碼
Ctrl+Alt+O 優化導入的類和包
Ctrl+S save

  • Alt+1

打開側邊欄

  • Shift+F6

rename 所有的文件,類名,函數名,屬性名都可以重命名,使用 Shift+F6 重命名,所有使用過這個名稱的地方都會跟着改變

  • Ctrl+R

run

  • Ctrl+w

我們經常會修改代碼,刪除代碼,那么就必然需要選中代碼,這個快捷鍵就是用來選中代碼的,連續使用會以此選中更多的代碼。

比如我們要修改字符串

fmt.Println("Sdfmsdf")

光標在 "" 中,那么我們使用一次 Ctrl+w 就會選中 "" 中的字符,就可以直接給修改或刪除了,我們可以繼續按,則會以此加上雙引號,以此加上括號,以此選中整個語句。

如果我們要刪除某個函數,可以對着函數名或直接在函數中多按幾次 Ctrl+w, 就會選中整個函數代碼塊了,當然直接對着函數名按的次數少一些。

如果我們按快了,也可以按 Ctrl+shift+w 來撤銷上一次選中。

Ctrl+/ 行注釋

Ctrl+shift+/ 快注釋

Ctrl+k git add and commit
Ctrk+shift+k git push

Ctrl+shift+space 智能提示

Ctrl+shift+f find in path
Ctrl+shift+r replace in path

Alt+j 選中相同的變量

Ctrl+shift+c 復制當前的文件的路徑

Ctrl+d 重復當前行或選中文本

Ctrl+x 剪切當前行

Ctrl+c 雙擊復制當前行

Ctrl+y 刪除當前行

插件

  • translate 插件

Ctrl+shift+y 取詞翻譯

Ctrl+shift+o 彈出翻譯彈窗

  • acejump-lite

fn+m 字符跳轉

代碼生成

最特殊的鍵 alt+enter

此 action name 是 show context actions

這個鍵的作用可以在 Settings>Editor>Intensions>go 中查看

最常用的幾個就是 struct 相關調用函數以及add comment

struct 相關

  • File all fields

使用 struct 時,補全 其所有 fileds,只限於第一層,若 fileds 有 struct ,則不 fill 子 struct, 在 使用的 struct 里使用即可

Before

type Address struct { Street string; City string }
type Person struct { Name string; Location Address }

_ = Person{}

After

type Address struct { Street string; City string }
type Person struct { Name string; Location Address }

_ = Persona{
	Name:     "",
	Location: Address{},
}
  • File all fileds recursively

使用 struct 時,補全 其所有 fileds,只限於第一層,若 fileds 有 struct ,則遞歸的 fill 所有 struct, 在 使用的 struct 里使用即可

Before

type Address struct { Street string; City string }
type Person struct { Name string; Location Address }

_ = Person{}

After

type Address struct { Street string; City string }
type Person struct { Name string; Location Address }

_ = Persona{
	Name: "",
	Location: Address{
		Street: "",
		City:   "",
	},
}
  • file fileds

使用 struct, 選擇一個 filed 補全, 在使用的 struct 里使用即可

Before

type Address struct { Street string; City string }
type Person struct { Name string; Location Address }

_ = Person{}

After

type Address struct { Street string; City string }
type Person struct { Name string; Location Address }

_ = Persona{
	Name:     "",
}
  • Generate constructor

給 struct 生成 new 方法,在 struct 的聲明處使用

Before

type Person struct {
	name string
	age int
}

After

type Person struct {
	name string
	age int
}

func NewPerson(name string, age int) *Person {
	return &Person{name: name, age: age}
} 
  • Generate getter

給 struct filed 生成 getter 方法,在 struct 聲明處,對着要生成的特定 file 即可

Before

type Person struct {
	name string
}

After

type Person struct {
	name string
}

func (p *Person) Name() string {
	return p.name
}
  • Generate setter

給 struct filed 生成 setter 方法,在 struct 聲明處,對着要生成的特定 file 即可

Before

type Person struct {
	name string
}

After

type Person struct {
	name string
}

func (p *Person) SetName(name string) {
	p.name = name
}
  • Generate getter and setter

給 struct filed 生成 getter 和 setter 方法,在 struct 聲明處,對着要生成的特定 file 即可

Before

type Person struct {
	name string
}

After

type Person struct {
	name string
}

func (p *Person) Name() string {
	return p.name
}

func (p *Person) SetName(name string) {
	p.name = name
}
  • Implement interface

給結構體實現某接口,接口可以是自定義的,也可以是已有的。也就是給結構體生成接口含有的所有方法。這個功能有快捷鍵 Ctrl+i, 對着結構體的聲明處使用即可

Before

package main

type A struct {}

type B interface {
	a1() int
	a2() int
	a3() int
}

After

package main

type A struct {}

func (*A) a1() int {
	panic("implement me")
}

func (*A) a2() int {
	panic("implement me")
}

func (*A) a3() int {
	panic("implement me")
}

type B interface {
	a1() int
	a2() int
	a3() int
}
  • Move field assignment to struct initialization

使用了一個 struct, 然后又寫了一個賦值語句,這個命令是把兩個語句合成一個語句,在 初始化語句里使用即可

Before

s := S{}
s.foo = `bar`

After

s := S{foo: `bar`}
  • Remove keys from struct literal

使用 struct 時,把 filed name 去掉,在使用 struct 時使用

Before

var _ = struct{int; string; slice []int}{string : "a", int : 2}

After

var _ = struct{int; string; slice []int}{2, "a", nil}

調用函數

  • ignore explicitly

調用函數時,有時函數會報黃,會出現這個選項,這個選項有點類似 Introduce to local variable , 不過后者是快速生成返回值,這個則是用 _ 占位符表示返回值

before

ioutil.WriteFile()

After

_ = ioutil.WriteFile()
  • do not report this method/function anymore

調用函數時,有時函數會報黃,會出現這個選項, 使用這個后這個函數班會再變黃,至於為什么會變黃,我猜是 warning, 具體原因暫時未知

  • Introduce to local variable

調用函數時,迅速生成賦值返回值變量,對着調用的函數名使用

Before

func Add(a int, b int) int {
	return a + b
}
func main() {
	Add(1, 2)
}

After

func Add(a int, b int) (int, error) {
	return a + b, nil
}
func main() {
	add, err := Add(1, 2)
}
  • Rename _

調用函數后,把沒有使用的賦值變量變為 _ , 對着沒有使用的變量使用即可

Before

func Add(a int, b int) (int, error) {
	return a + b, nil
}
func main() {
	a, err := Add(1, 2)
}

After

func Add(a int, b int) (int, error) {
	return a + b, nil
}
func main() {
	_, err := Add(1, 2)
}
  • Insert bank identifies to left side of assginment statement

調用函數時,若有多個返回值,而賦值的變量沒有返回值多,那么對着變量使用后,會自動補全返回值個數

Before

func Add(a int, b int) (int, error) {
	return a + b, nil
}
func main() {
	a := Add(1, 2)
}

After

func Add(a int, b int) (int, error) {
	return a + b, nil
}
func main() {
	a, _ := Add(1, 2)
}
  • Replace with ":"

調用函數時,若賦值的變量沒有聲明,那么對其使用就會直接聲明后賦值

Before

func Add(a int, b int) (int, error) {
	return a + b, nil
}
func main() {
	a = Add(1, 2)
}

AAfter

func Add(a int, b int) (int, error) {
	return a + b, nil
}
func main() {
	a := Add(1, 2)
}
  • Add missing return values

函數 return 返回值時,若個數不夠,那么在 return 使用會自動增加返回值

Before

func Add(a int, b int) (int, error) {
	return a + b
}

After

func Add(a int, b int) (int, error) {
	return a + b, nil
}
  • Remove 2nd result parameter from function

函數 return 返回值時,若個數不夠, 或者調用函數時,賦值的變量比返回值少,使用后會把返回值減少到對應個數

Before

func Add(a int, b int) (int, error) {
	return a + b, nil
}

func main() {
	a := Add(1, 2)
}

After

func Add(a int, b int) int {
	return a + b
}

func main() {
	a := Add(1, 2)
}

或者

Before

func Add(a int, b int) (int, error) {
	return a + b
}

After

func Add(a int, b int) int {
	return a + b
}

聲明變量

  • Add parens to declaration

給單個變量聲明時添加括號,在變量聲明處使用

Before

var a string

After

var (
	a string
)

這里說一下 import 時的情況,在 goland 中,只 import 了一個package,要加括號的話在 import 后直接打 ( 即可,goland 會自動把其放入括號中

  • Remove parens from declaration

與 Add parens to delartion 相反,去除括號

Before

var (
	a string
)

After

var a string
  • Merge all declaration

給連續三個以上的變量聲明划分為一組,空格隔開的不算,對着變量使用即可

Before

var a string

var b int
var c float32
var d bool

var e int

After

var a string

var (
	b int
	c float32
	d bool
)

var e int
  • split all declaration

與 Merge all declaration 相反,會把括號里的變量分開聲明

Before

var (
	a string
	b int
	c int
)

After

var a string
var b int
var c int
  • merge declaration up

把這個變量和上一個聲明的變量放在一個括號中,空格不影響

Before

var a string
var b int

After

var (
	a string
	b int
)
  • merge declaration up via comma

把這個變量和上一個聲明的變量放在一行,空格不影響

Before

var a int
var b int

After

var a, b int
  • split declaration by comma

於 merge declaration up via comma 相反,把一行聲明的變量變為多行聲明

Before

var a, b int

After

var a int
var b int
  • convert to short var declaration

把 var 變量的聲明格式變為更短的 := 格式,在 var 變量聲明處使用

Before

var x = 1

After

x := 1
  • convert to var declaration

與 convert to short var declaration 相反,把 := 聲明的變量變為 var 聲明的格式,在 := 變量聲明處使用

Before

x := 1

After

var x = 1

函數其他

  • Add comment

在聲明函數的地方,對着函數名可以生成此函數的注釋

Before

package foo

func Foo() {

}

After

package foo

// Foo 
func Foo() {

}
  • add format string argument

在支持格式化的函數的參數里, 即 ("") 的引號中使用。選擇一個變量后,會自動生成相應的格式化輸出。

如 int 類型 a, 輸入 a 后會自動生成 %d, 而無需記憶對應的意義。

Before

func log(count int) {
	fmt.Printf(`count is: `)
}

After

func log(count int) {
	fmt.Printf(`count is: %d`, count)
}
  • Expand signature types

在參數和返回值時,轉換類型的寫法, 在參數或返回值括號內使用即可

Before

func foo(s1, s2 string) (i1, i2 int) {
	return 0, 1
}

After

func foo(s1 string, s2 string) (i1 int, i2 int) {
	return 0, 1
}
  • Reuse signature types

與上面的 Expand signature types 相反

Before

func bar(s1 string, s2 string) (i1 int, i2 int) {
	return 0, 1
}

After

func bar(s1, s2 string) (i1, i2 int) {
	return 0, 1
}
  • Export

把私有 func, type, filed 變為公有的,在 func或 type 或 sturct 里的 filed 里使用即可

Before

func private() {}

After

func Private() {}
  • Invert if

把 if- else 語句反過來,在 操作符 處使用即可

Before

a := 1
if a >= 2 {
	fmt.Println("a >= 2")
} else {
	fmt.Println("a < 2")
}

After

a := 1
if a < 2 {
	fmt.Println("a < 2")
} else {
	fmt.Println("a >= 2")
}

單詞

  • typo change to

對着拼錯的單詞使用,在對標識符命名,寫注釋什么的很方便

Before

blak

After

black

導包

  • sync dependencies of

在 import 后添加想要拉的包 path, 任何使用這個 action, 可以直接拉包,類似 go get。

  • Add dot import alias

在導的包前或使用的包名中使用,可以直接用包里的函數

Before

package main

import "fmt"

func main() {
    fmt.Println("Hello World!")
}

After

package main

import . "fmt"

func main() {
    Println("Hello World!")
}
  • Remove dot import alias

和 Add dot import alias 相反,取消其效果,導的包前或使用的包名中使用

Before

package main

import . "fmt"

func main() {
    Println("Hello World!")
}

After

package main

import "fmt"

func main() {
    fmt.Println("Hello World!")
}
  • Add import alias

這個同樣在導的包前或使用的包名中使用,可以給包設置別名

Before

package main

import "fmt"

func main() {
    fmt.Println("Hello World!")
}

After

package main

import fmtAlias "fmt"

func main() {
    fmtAlias.Println("Hello World!")
}

操作表達式的改變

  • flip binary operator
  • negate expression
  • negate expression recurisively
  • negate topmostexpression
  • negate topmostexpression recurisively

這幾個都是不常用的(至少我沒怎么用到)

生成測試代碼 Ctrl+Shift+T

此 action name 是 go to test

這個鍵一共有 4 個功能

Test for functions

這個是最常用的,在函數內使用即可。

這個功能是生成函數測試。

go 中的測試文件需要在原有文件名后加上 _test, 測試函數需要在函數名前加上 Test ,參數也是特殊的。

如果手動生成的話比較麻煩且容易忘記,於是可以使用此快捷鍵。

如:

Before

db.go 中

func Hello {
	fmt.Println("Hello World")
}

After

生成 db_test.go 文件
其中 
func TestHello(t *testing.T) {
//...
}

Test for files

生成此 files 內的所有函數的 test

Test for package

生成此 package 內的所有函數的 test

empty test file

生成空 test file, 里面沒有 TestFunc

自動補全代碼 Ctrl+shfit+enter

  • 自動補全右括號

有時候要把莫東西加到括號中,可以先加上左括號,然后對着此行使用,會自動補全右括號並移動到下一行

Before

func main() {
	fmt.Println ("Hello World!"
}

After

func main() {
	fmt.Println("Hello Wrold!")
}
  • 自動補全大括號

有時候大括號多了,會不小心刪除右括號,這時候使用會自動生成右括號

Before

func main(){
	fmt.Println("hello World!")

After

func main() {
	fmt.Println("hello world!")
}

常用 action

  • find usage 查找方法被調用的地方


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM