7 "github.com/zyedidia/micro/cmd/micro/screen"
8 "github.com/zyedidia/micro/cmd/micro/util"
9 "github.com/zyedidia/tcell"
12 // MousePress is the event that should happen when a normal click happens
13 // This is almost always bound to left click
14 func (h *BufHandler) MousePress(e *tcell.EventMouse) bool {
18 // ScrollUpAction scrolls the view up
19 func (h *BufHandler) ScrollUpAction() bool {
23 // ScrollDownAction scrolls the view up
24 func (h *BufHandler) ScrollDownAction() bool {
28 // Center centers the view on the cursor
29 func (h *BufHandler) Center() bool {
33 // CursorUp moves the cursor up
34 func (h *BufHandler) CursorUp() bool {
35 h.Cursor.Deselect(true)
40 // CursorDown moves the cursor down
41 func (h *BufHandler) CursorDown() bool {
42 h.Cursor.Deselect(true)
47 // CursorLeft moves the cursor left
48 func (h *BufHandler) CursorLeft() bool {
49 h.Cursor.Deselect(true)
54 // CursorRight moves the cursor right
55 func (h *BufHandler) CursorRight() bool {
56 h.Cursor.Deselect(true)
61 // WordRight moves the cursor one word to the right
62 func (h *BufHandler) WordRight() bool {
63 h.Cursor.Deselect(true)
68 // WordLeft moves the cursor one word to the left
69 func (h *BufHandler) WordLeft() bool {
70 h.Cursor.Deselect(true)
75 // SelectUp selects up one line
76 func (h *BufHandler) SelectUp() bool {
77 if !h.Cursor.HasSelection() {
78 h.Cursor.OrigSelection[0] = h.Cursor.Loc
81 h.Cursor.SelectTo(h.Cursor.Loc)
85 // SelectDown selects down one line
86 func (h *BufHandler) SelectDown() bool {
87 if !h.Cursor.HasSelection() {
88 h.Cursor.OrigSelection[0] = h.Cursor.Loc
91 h.Cursor.SelectTo(h.Cursor.Loc)
95 // SelectLeft selects the character to the left of the cursor
96 func (h *BufHandler) SelectLeft() bool {
99 if loc.GreaterThan(count) {
102 if !h.Cursor.HasSelection() {
103 h.Cursor.OrigSelection[0] = loc
106 h.Cursor.SelectTo(h.Cursor.Loc)
110 // SelectRight selects the character to the right of the cursor
111 func (h *BufHandler) SelectRight() bool {
114 if loc.GreaterThan(count) {
117 if !h.Cursor.HasSelection() {
118 h.Cursor.OrigSelection[0] = loc
121 h.Cursor.SelectTo(h.Cursor.Loc)
125 // SelectWordRight selects the word to the right of the cursor
126 func (h *BufHandler) SelectWordRight() bool {
127 if !h.Cursor.HasSelection() {
128 h.Cursor.OrigSelection[0] = h.Cursor.Loc
131 h.Cursor.SelectTo(h.Cursor.Loc)
135 // SelectWordLeft selects the word to the left of the cursor
136 func (h *BufHandler) SelectWordLeft() bool {
137 if !h.Cursor.HasSelection() {
138 h.Cursor.OrigSelection[0] = h.Cursor.Loc
141 h.Cursor.SelectTo(h.Cursor.Loc)
145 // StartOfLine moves the cursor to the start of the line
146 func (h *BufHandler) StartOfLine() bool {
147 h.Cursor.Deselect(true)
151 h.Cursor.StartOfText()
156 // EndOfLine moves the cursor to the end of the line
157 func (h *BufHandler) EndOfLine() bool {
158 h.Cursor.Deselect(true)
163 // SelectLine selects the entire current line
164 func (h *BufHandler) SelectLine() bool {
165 h.Cursor.SelectLine()
169 // SelectToStartOfLine selects to the start of the current line
170 func (h *BufHandler) SelectToStartOfLine() bool {
171 if !h.Cursor.HasSelection() {
172 h.Cursor.OrigSelection[0] = h.Cursor.Loc
175 h.Cursor.SelectTo(h.Cursor.Loc)
179 // SelectToEndOfLine selects to the end of the current line
180 func (h *BufHandler) SelectToEndOfLine() bool {
181 if !h.Cursor.HasSelection() {
182 h.Cursor.OrigSelection[0] = h.Cursor.Loc
185 h.Cursor.SelectTo(h.Cursor.Loc)
189 // ParagraphPrevious moves the cursor to the previous empty line, or beginning of the buffer if there's none
190 func (h *BufHandler) ParagraphPrevious() bool {
192 for line = h.Cursor.Y; line > 0; line-- {
193 if len(h.Buf.LineBytes(line)) == 0 && line != h.Cursor.Y {
199 // If no empty line found. move cursor to end of buffer
201 h.Cursor.Loc = h.Buf.Start()
206 // ParagraphNext moves the cursor to the next empty line, or end of the buffer if there's none
207 func (h *BufHandler) ParagraphNext() bool {
209 for line = h.Cursor.Y; line < h.Buf.LinesNum(); line++ {
210 if len(h.Buf.LineBytes(line)) == 0 && line != h.Cursor.Y {
216 // If no empty line found. move cursor to end of buffer
217 if line == h.Buf.LinesNum() {
218 h.Cursor.Loc = h.Buf.End()
223 // Retab changes all tabs to spaces or all spaces to tabs depending
224 // on the user's settings
225 func (h *BufHandler) Retab() bool {
229 // CursorStart moves the cursor to the start of the buffer
230 func (h *BufHandler) CursorStart() bool {
231 h.Cursor.Deselect(true)
237 // CursorEnd moves the cursor to the end of the buffer
238 func (h *BufHandler) CursorEnd() bool {
239 h.Cursor.Deselect(true)
240 h.Cursor.Loc = h.Buf.End()
241 h.Cursor.StoreVisualX()
245 // SelectToStart selects the text from the cursor to the start of the buffer
246 func (h *BufHandler) SelectToStart() bool {
247 if !h.Cursor.HasSelection() {
248 h.Cursor.OrigSelection[0] = h.Cursor.Loc
251 h.Cursor.SelectTo(h.Buf.Start())
255 // SelectToEnd selects the text from the cursor to the end of the buffer
256 func (h *BufHandler) SelectToEnd() bool {
257 if !h.Cursor.HasSelection() {
258 h.Cursor.OrigSelection[0] = h.Cursor.Loc
261 h.Cursor.SelectTo(h.Buf.End())
265 // InsertSpace inserts a space
266 func (h *BufHandler) InsertSpace() bool {
267 if h.Cursor.HasSelection() {
268 h.Cursor.DeleteSelection()
269 h.Cursor.ResetSelection()
271 h.Buf.Insert(h.Cursor.Loc, " ")
275 // InsertNewline inserts a newline plus possible some whitespace if autoindent is on
276 func (h *BufHandler) InsertNewline() bool {
280 // Backspace deletes the previous character
281 func (h *BufHandler) Backspace() bool {
282 if h.Cursor.HasSelection() {
283 h.Cursor.DeleteSelection()
284 h.Cursor.ResetSelection()
285 } else if h.Cursor.Loc.GreaterThan(h.Buf.Start()) {
286 // We have to do something a bit hacky here because we want to
287 // delete the line by first moving left and then deleting backwards
288 // but the undo redo would place the cursor in the wrong place
289 // So instead we move left, save the position, move back, delete
290 // and restore the position
292 // If the user is using spaces instead of tabs and they are deleting
293 // whitespace at the start of the line, we should delete as if it's a
294 // tab (tabSize number of spaces)
295 lineStart := util.SliceStart(h.Buf.LineBytes(h.Cursor.Y), h.Cursor.X)
296 tabSize := int(h.Buf.Settings["tabsize"].(float64))
297 if h.Buf.Settings["tabstospaces"].(bool) && util.IsSpaces(lineStart) && len(lineStart) != 0 && utf8.RuneCount(lineStart)%tabSize == 0 {
299 h.Buf.Remove(loc.Move(-tabSize, h.Buf), loc)
302 h.Buf.Remove(loc.Move(-1, h.Buf), loc)
305 h.Cursor.LastVisualX = h.Cursor.GetVisualX()
309 // DeleteWordRight deletes the word to the right of the cursor
310 func (h *BufHandler) DeleteWordRight() bool {
314 // DeleteWordLeft deletes the word to the left of the cursor
315 func (h *BufHandler) DeleteWordLeft() bool {
319 // Delete deletes the next character
320 func (h *BufHandler) Delete() bool {
324 // IndentSelection indents the current selection
325 func (h *BufHandler) IndentSelection() bool {
329 // OutdentLine moves the current line back one indentation
330 func (h *BufHandler) OutdentLine() bool {
334 // OutdentSelection takes the current selection and moves it back one indent level
335 func (h *BufHandler) OutdentSelection() bool {
339 // InsertTab inserts a tab or spaces
340 func (h *BufHandler) InsertTab() bool {
344 // SaveAll saves all open buffers
345 func (h *BufHandler) SaveAll() bool {
349 // Save the buffer to disk
350 func (h *BufHandler) Save() bool {
355 // SaveAs saves the buffer to disk with the given name
356 func (h *BufHandler) SaveAs() bool {
360 // Find opens a prompt and searches forward for the input
361 func (h *BufHandler) Find() bool {
365 // FindNext searches forwards for the last used search term
366 func (h *BufHandler) FindNext() bool {
370 // FindPrevious searches backwards for the last used search term
371 func (h *BufHandler) FindPrevious() bool {
375 // Undo undoes the last action
376 func (h *BufHandler) Undo() bool {
380 // Redo redoes the last action
381 func (h *BufHandler) Redo() bool {
385 // Copy the selection to the system clipboard
386 func (h *BufHandler) Copy() bool {
390 // CutLine cuts the current line to the clipboard
391 func (h *BufHandler) CutLine() bool {
395 // Cut the selection to the system clipboard
396 func (h *BufHandler) Cut() bool {
400 // DuplicateLine duplicates the current line or selection
401 func (h *BufHandler) DuplicateLine() bool {
405 // DeleteLine deletes the current line
406 func (h *BufHandler) DeleteLine() bool {
410 // MoveLinesUp moves up the current line or selected lines if any
411 func (h *BufHandler) MoveLinesUp() bool {
415 // MoveLinesDown moves down the current line or selected lines if any
416 func (h *BufHandler) MoveLinesDown() bool {
420 // Paste whatever is in the system clipboard into the buffer
421 // Delete and paste if the user has a selection
422 func (h *BufHandler) Paste() bool {
426 // PastePrimary pastes from the primary clipboard (only use on linux)
427 func (h *BufHandler) PastePrimary() bool {
431 // JumpToMatchingBrace moves the cursor to the matching brace if it is
432 // currently on a brace
433 func (h *BufHandler) JumpToMatchingBrace() bool {
437 // SelectAll selects the entire buffer
438 func (h *BufHandler) SelectAll() bool {
442 // OpenFile opens a new file in the buffer
443 func (h *BufHandler) OpenFile() bool {
447 // Start moves the viewport to the start of the buffer
448 func (h *BufHandler) Start() bool {
452 // End moves the viewport to the end of the buffer
453 func (h *BufHandler) End() bool {
457 // PageUp scrolls the view up a page
458 func (h *BufHandler) PageUp() bool {
462 // PageDown scrolls the view down a page
463 func (h *BufHandler) PageDown() bool {
467 // SelectPageUp selects up one page
468 func (h *BufHandler) SelectPageUp() bool {
472 // SelectPageDown selects down one page
473 func (h *BufHandler) SelectPageDown() bool {
477 // CursorPageUp places the cursor a page up
478 func (h *BufHandler) CursorPageUp() bool {
482 // CursorPageDown places the cursor a page up
483 func (h *BufHandler) CursorPageDown() bool {
487 // HalfPageUp scrolls the view up half a page
488 func (h *BufHandler) HalfPageUp() bool {
492 // HalfPageDown scrolls the view down half a page
493 func (h *BufHandler) HalfPageDown() bool {
497 // ToggleRuler turns line numbers off and on
498 func (h *BufHandler) ToggleRuler() bool {
502 // JumpLine jumps to a line and moves the view accordingly.
503 func (h *BufHandler) JumpLine() bool {
507 // ClearStatus clears the messenger bar
508 func (h *BufHandler) ClearStatus() bool {
512 // ToggleHelp toggles the help screen
513 func (h *BufHandler) ToggleHelp() bool {
517 // ToggleKeyMenu toggles the keymenu option and resizes all tabs
518 func (h *BufHandler) ToggleKeyMenu() bool {
522 // ShellMode opens a terminal to run a shell command
523 func (h *BufHandler) ShellMode() bool {
527 // CommandMode lets the user enter a command
528 func (h *BufHandler) CommandMode() bool {
532 // ToggleOverwriteMode lets the user toggle the text overwrite mode
533 func (h *BufHandler) ToggleOverwriteMode() bool {
537 // Escape leaves current mode
538 func (h *BufHandler) Escape() bool {
542 // Quit this will close the current tab or view that is open
543 func (h *BufHandler) Quit() bool {
549 // QuitAll quits the whole editor; all splits and tabs
550 func (h *BufHandler) QuitAll() bool {
554 // AddTab adds a new tab with an empty buffer
555 func (h *BufHandler) AddTab() bool {
559 // PreviousTab switches to the previous tab in the tab list
560 func (h *BufHandler) PreviousTab() bool {
564 // NextTab switches to the next tab in the tab list
565 func (h *BufHandler) NextTab() bool {
569 // VSplitBinding opens an empty vertical split
570 func (h *BufHandler) VSplitBinding() bool {
574 // HSplitBinding opens an empty horizontal split
575 func (h *BufHandler) HSplitBinding() bool {
579 // Unsplit closes all splits in the current tab except the active one
580 func (h *BufHandler) Unsplit() bool {
584 // NextSplit changes the view to the next split
585 func (h *BufHandler) NextSplit() bool {
589 // PreviousSplit changes the view to the previous split
590 func (h *BufHandler) PreviousSplit() bool {
594 var curMacro []interface{}
595 var recordingMacro bool
597 // ToggleMacro toggles recording of a macro
598 func (h *BufHandler) ToggleMacro() bool {
602 // PlayMacro plays back the most recently recorded macro
603 func (h *BufHandler) PlayMacro() bool {
607 // SpawnMultiCursor creates a new multiple cursor at the next occurrence of the current selection or current word
608 func (h *BufHandler) SpawnMultiCursor() bool {
612 // SpawnMultiCursorSelect adds a cursor at the beginning of each line of a selection
613 func (h *BufHandler) SpawnMultiCursorSelect() bool {
617 // MouseMultiCursor is a mouse action which puts a new cursor at the mouse position
618 func (h *BufHandler) MouseMultiCursor(e *tcell.EventMouse) bool {
622 // SkipMultiCursor moves the current multiple cursor to the next available position
623 func (h *BufHandler) SkipMultiCursor() bool {
627 // RemoveMultiCursor removes the latest multiple cursor
628 func (h *BufHandler) RemoveMultiCursor() bool {
632 // RemoveAllMultiCursors removes all cursors except the base cursor
633 func (h *BufHandler) RemoveAllMultiCursors() bool {