]> git.lizzy.rs Git - micro.git/blob - cmd/micro/action/actions.go
f47bcd6a83d27e1422cf625197575a46a0ad1d0c
[micro.git] / cmd / micro / action / actions.go
1 package action
2
3 import (
4         "os"
5         "unicode/utf8"
6
7         "github.com/zyedidia/micro/cmd/micro/screen"
8         "github.com/zyedidia/micro/cmd/micro/util"
9         "github.com/zyedidia/tcell"
10 )
11
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 {
15         return false
16 }
17
18 // ScrollUpAction scrolls the view up
19 func (h *BufHandler) ScrollUpAction() bool {
20         return false
21 }
22
23 // ScrollDownAction scrolls the view up
24 func (h *BufHandler) ScrollDownAction() bool {
25         return false
26 }
27
28 // Center centers the view on the cursor
29 func (h *BufHandler) Center() bool {
30         return true
31 }
32
33 // CursorUp moves the cursor up
34 func (h *BufHandler) CursorUp() bool {
35         h.Cursor.Deselect(true)
36         h.Cursor.Up()
37         return true
38 }
39
40 // CursorDown moves the cursor down
41 func (h *BufHandler) CursorDown() bool {
42         h.Cursor.Deselect(true)
43         h.Cursor.Down()
44         return true
45 }
46
47 // CursorLeft moves the cursor left
48 func (h *BufHandler) CursorLeft() bool {
49         h.Cursor.Deselect(true)
50         h.Cursor.Left()
51         return true
52 }
53
54 // CursorRight moves the cursor right
55 func (h *BufHandler) CursorRight() bool {
56         h.Cursor.Deselect(true)
57         h.Cursor.Right()
58         return true
59 }
60
61 // WordRight moves the cursor one word to the right
62 func (h *BufHandler) WordRight() bool {
63         h.Cursor.Deselect(true)
64         h.Cursor.WordRight()
65         return true
66 }
67
68 // WordLeft moves the cursor one word to the left
69 func (h *BufHandler) WordLeft() bool {
70         h.Cursor.Deselect(true)
71         h.Cursor.WordLeft()
72         return true
73 }
74
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
79         }
80         h.Cursor.Up()
81         h.Cursor.SelectTo(h.Cursor.Loc)
82         return true
83 }
84
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
89         }
90         h.Cursor.Down()
91         h.Cursor.SelectTo(h.Cursor.Loc)
92         return true
93 }
94
95 // SelectLeft selects the character to the left of the cursor
96 func (h *BufHandler) SelectLeft() bool {
97         loc := h.Cursor.Loc
98         count := h.Buf.End()
99         if loc.GreaterThan(count) {
100                 loc = count
101         }
102         if !h.Cursor.HasSelection() {
103                 h.Cursor.OrigSelection[0] = loc
104         }
105         h.Cursor.Left()
106         h.Cursor.SelectTo(h.Cursor.Loc)
107         return true
108 }
109
110 // SelectRight selects the character to the right of the cursor
111 func (h *BufHandler) SelectRight() bool {
112         loc := h.Cursor.Loc
113         count := h.Buf.End()
114         if loc.GreaterThan(count) {
115                 loc = count
116         }
117         if !h.Cursor.HasSelection() {
118                 h.Cursor.OrigSelection[0] = loc
119         }
120         h.Cursor.Right()
121         h.Cursor.SelectTo(h.Cursor.Loc)
122         return true
123 }
124
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
129         }
130         h.Cursor.WordRight()
131         h.Cursor.SelectTo(h.Cursor.Loc)
132         return true
133 }
134
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
139         }
140         h.Cursor.WordLeft()
141         h.Cursor.SelectTo(h.Cursor.Loc)
142         return true
143 }
144
145 // StartOfLine moves the cursor to the start of the line
146 func (h *BufHandler) StartOfLine() bool {
147         h.Cursor.Deselect(true)
148         if h.Cursor.X != 0 {
149                 h.Cursor.Start()
150         } else {
151                 h.Cursor.StartOfText()
152         }
153         return true
154 }
155
156 // EndOfLine moves the cursor to the end of the line
157 func (h *BufHandler) EndOfLine() bool {
158         h.Cursor.Deselect(true)
159         h.Cursor.End()
160         return true
161 }
162
163 // SelectLine selects the entire current line
164 func (h *BufHandler) SelectLine() bool {
165         h.Cursor.SelectLine()
166         return true
167 }
168
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
173         }
174         h.Cursor.Start()
175         h.Cursor.SelectTo(h.Cursor.Loc)
176         return true
177 }
178
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
183         }
184         h.Cursor.End()
185         h.Cursor.SelectTo(h.Cursor.Loc)
186         return true
187 }
188
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 {
191         var line int
192         for line = h.Cursor.Y; line > 0; line-- {
193                 if len(h.Buf.LineBytes(line)) == 0 && line != h.Cursor.Y {
194                         h.Cursor.X = 0
195                         h.Cursor.Y = line
196                         break
197                 }
198         }
199         // If no empty line found. move cursor to end of buffer
200         if line == 0 {
201                 h.Cursor.Loc = h.Buf.Start()
202         }
203         return true
204 }
205
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 {
208         var line int
209         for line = h.Cursor.Y; line < h.Buf.LinesNum(); line++ {
210                 if len(h.Buf.LineBytes(line)) == 0 && line != h.Cursor.Y {
211                         h.Cursor.X = 0
212                         h.Cursor.Y = line
213                         break
214                 }
215         }
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()
219         }
220         return true
221 }
222
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 {
226         return true
227 }
228
229 // CursorStart moves the cursor to the start of the buffer
230 func (h *BufHandler) CursorStart() bool {
231         h.Cursor.Deselect(true)
232         h.Cursor.X = 0
233         h.Cursor.Y = 0
234         return true
235 }
236
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()
242         return true
243 }
244
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
249         }
250         h.CursorStart()
251         h.Cursor.SelectTo(h.Buf.Start())
252         return true
253 }
254
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
259         }
260         h.CursorEnd()
261         h.Cursor.SelectTo(h.Buf.End())
262         return true
263 }
264
265 // InsertSpace inserts a space
266 func (h *BufHandler) InsertSpace() bool {
267         if h.Cursor.HasSelection() {
268                 h.Cursor.DeleteSelection()
269                 h.Cursor.ResetSelection()
270         }
271         h.Buf.Insert(h.Cursor.Loc, " ")
272         return true
273 }
274
275 // InsertNewline inserts a newline plus possible some whitespace if autoindent is on
276 func (h *BufHandler) InsertNewline() bool {
277         return true
278 }
279
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
291
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 {
298                         loc := h.Cursor.Loc
299                         h.Buf.Remove(loc.Move(-tabSize, h.Buf), loc)
300                 } else {
301                         loc := h.Cursor.Loc
302                         h.Buf.Remove(loc.Move(-1, h.Buf), loc)
303                 }
304         }
305         h.Cursor.LastVisualX = h.Cursor.GetVisualX()
306         return true
307 }
308
309 // DeleteWordRight deletes the word to the right of the cursor
310 func (h *BufHandler) DeleteWordRight() bool {
311         return true
312 }
313
314 // DeleteWordLeft deletes the word to the left of the cursor
315 func (h *BufHandler) DeleteWordLeft() bool {
316         return true
317 }
318
319 // Delete deletes the next character
320 func (h *BufHandler) Delete() bool {
321         return true
322 }
323
324 // IndentSelection indents the current selection
325 func (h *BufHandler) IndentSelection() bool {
326         return false
327 }
328
329 // OutdentLine moves the current line back one indentation
330 func (h *BufHandler) OutdentLine() bool {
331         return true
332 }
333
334 // OutdentSelection takes the current selection and moves it back one indent level
335 func (h *BufHandler) OutdentSelection() bool {
336         return false
337 }
338
339 // InsertTab inserts a tab or spaces
340 func (h *BufHandler) InsertTab() bool {
341         return true
342 }
343
344 // SaveAll saves all open buffers
345 func (h *BufHandler) SaveAll() bool {
346         return false
347 }
348
349 // Save the buffer to disk
350 func (h *BufHandler) Save() bool {
351         h.Buf.Save()
352         return false
353 }
354
355 // SaveAs saves the buffer to disk with the given name
356 func (h *BufHandler) SaveAs() bool {
357         return false
358 }
359
360 // Find opens a prompt and searches forward for the input
361 func (h *BufHandler) Find() bool {
362         return true
363 }
364
365 // FindNext searches forwards for the last used search term
366 func (h *BufHandler) FindNext() bool {
367         return true
368 }
369
370 // FindPrevious searches backwards for the last used search term
371 func (h *BufHandler) FindPrevious() bool {
372         return true
373 }
374
375 // Undo undoes the last action
376 func (h *BufHandler) Undo() bool {
377         return true
378 }
379
380 // Redo redoes the last action
381 func (h *BufHandler) Redo() bool {
382         return true
383 }
384
385 // Copy the selection to the system clipboard
386 func (h *BufHandler) Copy() bool {
387         return true
388 }
389
390 // CutLine cuts the current line to the clipboard
391 func (h *BufHandler) CutLine() bool {
392         return true
393 }
394
395 // Cut the selection to the system clipboard
396 func (h *BufHandler) Cut() bool {
397         return true
398 }
399
400 // DuplicateLine duplicates the current line or selection
401 func (h *BufHandler) DuplicateLine() bool {
402         return true
403 }
404
405 // DeleteLine deletes the current line
406 func (h *BufHandler) DeleteLine() bool {
407         return true
408 }
409
410 // MoveLinesUp moves up the current line or selected lines if any
411 func (h *BufHandler) MoveLinesUp() bool {
412         return true
413 }
414
415 // MoveLinesDown moves down the current line or selected lines if any
416 func (h *BufHandler) MoveLinesDown() bool {
417         return true
418 }
419
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 {
423         return true
424 }
425
426 // PastePrimary pastes from the primary clipboard (only use on linux)
427 func (h *BufHandler) PastePrimary() bool {
428         return true
429 }
430
431 // JumpToMatchingBrace moves the cursor to the matching brace if it is
432 // currently on a brace
433 func (h *BufHandler) JumpToMatchingBrace() bool {
434         return true
435 }
436
437 // SelectAll selects the entire buffer
438 func (h *BufHandler) SelectAll() bool {
439         return true
440 }
441
442 // OpenFile opens a new file in the buffer
443 func (h *BufHandler) OpenFile() bool {
444         return false
445 }
446
447 // Start moves the viewport to the start of the buffer
448 func (h *BufHandler) Start() bool {
449         return false
450 }
451
452 // End moves the viewport to the end of the buffer
453 func (h *BufHandler) End() bool {
454         return false
455 }
456
457 // PageUp scrolls the view up a page
458 func (h *BufHandler) PageUp() bool {
459         return false
460 }
461
462 // PageDown scrolls the view down a page
463 func (h *BufHandler) PageDown() bool {
464         return false
465 }
466
467 // SelectPageUp selects up one page
468 func (h *BufHandler) SelectPageUp() bool {
469         return true
470 }
471
472 // SelectPageDown selects down one page
473 func (h *BufHandler) SelectPageDown() bool {
474         return true
475 }
476
477 // CursorPageUp places the cursor a page up
478 func (h *BufHandler) CursorPageUp() bool {
479         return true
480 }
481
482 // CursorPageDown places the cursor a page up
483 func (h *BufHandler) CursorPageDown() bool {
484         return true
485 }
486
487 // HalfPageUp scrolls the view up half a page
488 func (h *BufHandler) HalfPageUp() bool {
489         return false
490 }
491
492 // HalfPageDown scrolls the view down half a page
493 func (h *BufHandler) HalfPageDown() bool {
494         return false
495 }
496
497 // ToggleRuler turns line numbers off and on
498 func (h *BufHandler) ToggleRuler() bool {
499         return false
500 }
501
502 // JumpLine jumps to a line and moves the view accordingly.
503 func (h *BufHandler) JumpLine() bool {
504         return false
505 }
506
507 // ClearStatus clears the messenger bar
508 func (h *BufHandler) ClearStatus() bool {
509         return false
510 }
511
512 // ToggleHelp toggles the help screen
513 func (h *BufHandler) ToggleHelp() bool {
514         return true
515 }
516
517 // ToggleKeyMenu toggles the keymenu option and resizes all tabs
518 func (h *BufHandler) ToggleKeyMenu() bool {
519         return true
520 }
521
522 // ShellMode opens a terminal to run a shell command
523 func (h *BufHandler) ShellMode() bool {
524         return false
525 }
526
527 // CommandMode lets the user enter a command
528 func (h *BufHandler) CommandMode() bool {
529         return false
530 }
531
532 // ToggleOverwriteMode lets the user toggle the text overwrite mode
533 func (h *BufHandler) ToggleOverwriteMode() bool {
534         return false
535 }
536
537 // Escape leaves current mode
538 func (h *BufHandler) Escape() bool {
539         return false
540 }
541
542 // Quit this will close the current tab or view that is open
543 func (h *BufHandler) Quit() bool {
544         screen.Screen.Fini()
545         os.Exit(0)
546         return false
547 }
548
549 // QuitAll quits the whole editor; all splits and tabs
550 func (h *BufHandler) QuitAll() bool {
551         return false
552 }
553
554 // AddTab adds a new tab with an empty buffer
555 func (h *BufHandler) AddTab() bool {
556         return true
557 }
558
559 // PreviousTab switches to the previous tab in the tab list
560 func (h *BufHandler) PreviousTab() bool {
561         return false
562 }
563
564 // NextTab switches to the next tab in the tab list
565 func (h *BufHandler) NextTab() bool {
566         return false
567 }
568
569 // VSplitBinding opens an empty vertical split
570 func (h *BufHandler) VSplitBinding() bool {
571         return false
572 }
573
574 // HSplitBinding opens an empty horizontal split
575 func (h *BufHandler) HSplitBinding() bool {
576         return false
577 }
578
579 // Unsplit closes all splits in the current tab except the active one
580 func (h *BufHandler) Unsplit() bool {
581         return false
582 }
583
584 // NextSplit changes the view to the next split
585 func (h *BufHandler) NextSplit() bool {
586         return false
587 }
588
589 // PreviousSplit changes the view to the previous split
590 func (h *BufHandler) PreviousSplit() bool {
591         return false
592 }
593
594 var curMacro []interface{}
595 var recordingMacro bool
596
597 // ToggleMacro toggles recording of a macro
598 func (h *BufHandler) ToggleMacro() bool {
599         return true
600 }
601
602 // PlayMacro plays back the most recently recorded macro
603 func (h *BufHandler) PlayMacro() bool {
604         return true
605 }
606
607 // SpawnMultiCursor creates a new multiple cursor at the next occurrence of the current selection or current word
608 func (h *BufHandler) SpawnMultiCursor() bool {
609         return false
610 }
611
612 // SpawnMultiCursorSelect adds a cursor at the beginning of each line of a selection
613 func (h *BufHandler) SpawnMultiCursorSelect() bool {
614         return false
615 }
616
617 // MouseMultiCursor is a mouse action which puts a new cursor at the mouse position
618 func (h *BufHandler) MouseMultiCursor(e *tcell.EventMouse) bool {
619         return false
620 }
621
622 // SkipMultiCursor moves the current multiple cursor to the next available position
623 func (h *BufHandler) SkipMultiCursor() bool {
624         return false
625 }
626
627 // RemoveMultiCursor removes the latest multiple cursor
628 func (h *BufHandler) RemoveMultiCursor() bool {
629         return false
630 }
631
632 // RemoveAllMultiCursors removes all cursors except the base cursor
633 func (h *BufHandler) RemoveAllMultiCursors() bool {
634         return false
635 }