rm: erroneous addons folder

This commit is contained in:
Djairo Hougee 2025-11-12 16:47:46 +01:00
parent 6ab83e0f34
commit ef75320c81
24 changed files with 0 additions and 3009 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1 +0,0 @@
uid://t4imnbu2n5vw

View File

@ -1,179 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="409.99237"
height="551.82874"
version="1.1"
id="svg3763"
sodipodi:docname="iconsvg.svg"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)">
<defs
id="defs3767" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="3840"
inkscape:window-height="2089"
id="namedview3765"
showgrid="false"
inkscape:zoom="0.88187112"
inkscape:cx="-391.82984"
inkscape:cy="385.67966"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg3763" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="g3845"
transform="matrix(4.3859694,0,0,4.3859694,-75.706218,-87.385926)">
<g
id="g3823"
transform="matrix(0.10073078,0,0,0.10073078,12.425923,2.256365)"
style="stroke-width:9.92745972">
<path
id="path3807"
d="m 0,0 c 0,0 -0.325,1.994 -0.515,1.976 l -36.182,-3.491 c -2.879,-0.278 -5.115,-2.574 -5.317,-5.459 l -0.994,-14.247 -27.992,-1.997 -1.904,12.912 c -0.424,2.872 -2.932,5.037 -5.835,5.037 h -38.188 c -2.902,0 -5.41,-2.165 -5.834,-5.037 l -1.905,-12.912 -27.992,1.997 -0.994,14.247 c -0.202,2.886 -2.438,5.182 -5.317,5.46 l -36.2,3.49 c -0.187,0.018 -0.324,-1.978 -0.511,-1.978 l -0.049,-7.83 30.658,-4.944 1.004,-14.374 c 0.203,-2.91 2.551,-5.263 5.463,-5.472 l 38.551,-2.75 c 0.146,-0.01 0.29,-0.016 0.434,-0.016 2.897,0 5.401,2.166 5.825,5.038 l 1.959,13.286 h 28.005 l 1.959,-13.286 c 0.423,-2.871 2.93,-5.037 5.831,-5.037 0.142,0 0.284,0.005 0.423,0.015 l 38.556,2.75 c 2.911,0.209 5.26,2.562 5.463,5.472 l 1.003,14.374 30.645,4.966 z"
inkscape:connector-curvature="0"
style="fill:#ffffff"
transform="matrix(4.162611,0,0,-4.162611,919.24059,771.67186)" />
<path
id="path3809"
transform="matrix(4.162611,0,0,-4.162611,104.69892,525.90697)"
d="m 0,0 v -47.514 -6.035 -5.492 c 0.108,-0.001 0.216,-0.005 0.323,-0.015 l 36.196,-3.49 c 1.896,-0.183 3.382,-1.709 3.514,-3.609 l 1.116,-15.978 31.574,-2.253 2.175,14.747 c 0.282,1.912 1.922,3.329 3.856,3.329 h 38.188 c 1.933,0 3.573,-1.417 3.855,-3.329 l 2.175,-14.747 31.575,2.253 1.115,15.978 c 0.133,1.9 1.618,3.425 3.514,3.609 l 36.182,3.49 c 0.107,0.01 0.214,0.014 0.322,0.015 v 4.711 l 0.015,0.005 V 0 c 5.09692,6.4164715 9.92323,13.494208 13.621,19.449 -5.651,9.62 -12.575,18.217 -19.976,26.182 -6.864,-3.455 -13.531,-7.369 -19.828,-11.534 -3.151,3.132 -6.7,5.694 -10.186,8.372 -3.425,2.751 -7.285,4.768 -10.946,7.118 1.09,8.117 1.629,16.108 1.846,24.448 -9.446,4.754 -19.519,7.906 -29.708,10.17 -4.068,-6.837 -7.788,-14.241 -11.028,-21.479 -3.842,0.642 -7.702,0.88 -11.567,0.926 v 0.006 c -0.027,0 -0.052,-0.006 -0.075,-0.006 -0.024,0 -0.049,0.006 -0.073,0.006 V 63.652 C 93.903,63.606 90.046,63.368 86.203,62.726 82.965,69.964 79.247,77.368 75.173,84.205 64.989,81.941 54.915,78.789 45.47,74.035 45.686,65.695 46.225,57.704 47.318,49.587 43.65,47.237 39.795,45.22 36.369,42.469 32.888,39.791 29.333,37.229 26.181,34.097 19.884,38.262 13.219,42.176 6.353,45.631 -1.048,37.666 -7.968,29.069 -13.621,19.449 -9.1783421,12.475308 -4.4130298,5.4661124 0,0 Z"
inkscape:connector-curvature="0"
style="fill:#478cbf" />
<path
id="path3811"
d="m 0,0 -1.121,-16.063 c -0.135,-1.936 -1.675,-3.477 -3.611,-3.616 l -38.555,-2.751 c -0.094,-0.007 -0.188,-0.01 -0.281,-0.01 -1.916,0 -3.569,1.406 -3.852,3.33 l -2.211,14.994 H -81.09 l -2.211,-14.994 c -0.297,-2.018 -2.101,-3.469 -4.133,-3.32 l -38.555,2.751 c -1.936,0.139 -3.476,1.68 -3.611,3.616 L -130.721,0 -163.268,3.138 c 0.015,-3.498 0.06,-7.33 0.06,-8.093 0,-34.374 43.605,-50.896 97.781,-51.086 h 0.066 0.067 c 54.176,0.19 97.766,16.712 97.766,51.086 0,0.777 0.047,4.593 0.063,8.093 z"
inkscape:connector-curvature="0"
style="fill:#478cbf"
transform="matrix(4.162611,0,0,-4.162611,784.07144,817.24284)" />
<path
id="path3813"
transform="matrix(4.162611,0,0,-4.162611,389.21484,625.67104)"
d="m 0,0 c 0,-12.052 -9.765,-21.815 -21.813,-21.815 -12.042,0 -21.81,9.763 -21.81,21.815 0,12.044 9.768,21.802 21.81,21.802 C -9.765,21.802 0,12.044 0,0"
inkscape:connector-curvature="0"
style="fill:#ffffff" />
<path
id="path3815"
transform="matrix(4.162611,0,0,-4.162611,367.36686,631.05679)"
d="m 0,0 c 0,-7.994 -6.479,-14.473 -14.479,-14.473 -7.996,0 -14.479,6.479 -14.479,14.473 0,7.994 6.483,14.479 14.479,14.479 C -6.479,14.479 0,7.994 0,0"
inkscape:connector-curvature="0"
style="fill:#414042" />
<path
id="path3817"
transform="matrix(4.162611,0,0,-4.162611,511.99336,724.73954)"
d="m 0,0 c -3.878,0 -7.021,2.858 -7.021,6.381 v 20.081 c 0,3.52 3.143,6.381 7.021,6.381 3.878,0 7.028,-2.861 7.028,-6.381 V 6.381 C 7.028,2.858 3.878,0 0,0"
inkscape:connector-curvature="0"
style="fill:#ffffff" />
<path
id="path3819"
transform="matrix(4.162611,0,0,-4.162611,634.78706,625.67104)"
d="m 0,0 c 0,-12.052 9.765,-21.815 21.815,-21.815 12.041,0 21.808,9.763 21.808,21.815 0,12.044 -9.767,21.802 -21.808,21.802 C 9.765,21.802 0,12.044 0,0"
inkscape:connector-curvature="0"
style="fill:#ffffff" />
<path
id="path3821"
transform="matrix(4.162611,0,0,-4.162611,656.64056,631.05679)"
d="m 0,0 c 0,-7.994 6.477,-14.473 14.471,-14.473 8.002,0 14.479,6.479 14.479,14.473 0,7.994 -6.477,14.479 -14.479,14.479 C 6.477,14.479 0,7.994 0,0"
inkscape:connector-curvature="0"
style="fill:#414042" />
</g>
</g>
<g
id="layer1"
transform="matrix(0.7294074,0,0,0.7294074,-45.912295,80.565241)">
<g
id="g3699"
transform="matrix(1.532388,0,0,1.3939671,-54.912136,-41.792396)">
<path
id="path3650"
d="m 114.65715,353.09353 h 47.80701 l 2.91261,3.20613 v 9.83953 l -2.31001,3.09557 h -5.22261 v 48.86596 l 44.99482,-48.86596 h -7.43218 l -2.61131,-3.09557 v -10.39231 l 2.41044,-2.43224 h 48.40962 l 2.41043,2.65335 v 9.72897 L 136.55196,489.29907 h -12.45393 l -3.60484,-2.291 V 368.79254 h -6.03691 l -2.20956,-2.43224 v -10.39231 z"
style="fill:none;stroke:#000000;stroke-width:8.34521198;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
inkscape:connector-curvature="0" />
<path
id="path3640"
d="m 162.97227,358.09475 2.6987,-1.5635 -2.76971,-3.04884 h -48.22135 l -2.45013,2.69704 v 10.20187 l 2.71645,2.9902 1.29608,-2.9902 -1.70443,-1.87621 v -7.19212 l 1.27832,-1.2508 h 46.01979 z"
style="fill:#478cbf;fill-opacity:1;stroke:#000000;stroke-width:0.41726059px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
inkscape:connector-curvature="0" />
<path
d="m 197.06456,355.74729 -1.70266,1.87425 v 6.88137 l 1.49138,1.64168 h 7.87946 v 6.6488 l -52.12379,58.1565 v -64.72321 h 8.66244 l 1.77723,-1.95634 v -6.96346 l -1.64052,-1.39542 h -45.58657 l -1.49138,1.64168 v 7.11394 l 1.51624,1.66904 h 7.92918 v 119.18594 l 1.49138,1.64168 h 9.01043 L 243.50867,363.0938 v -5.47226 l -1.70266,-1.87425 z"
id="path3632"
style="fill:none;stroke:#000000;stroke-width:0.41726059px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
inkscape:connector-curvature="0" />
<path
id="path3646"
d="m 123.69629,366.13919 v 119.40096 l 1.40609,1.7689 -1.10266,2.31328 -3.1156,-3.41884 V 369.23476 Z"
style="fill:#478cbf;fill-opacity:1;stroke:#000000;stroke-width:0.41726059px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
inkscape:connector-curvature="0" />
<path
id="path3644"
d="m 115.90579,366.13919 -0.80348,2.87446 h 5.82523 l 3.21391,-2.87446 z"
style="fill:#478cbf;fill-opacity:1;stroke:#000000;stroke-width:0.41726059px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
inkscape:connector-curvature="0" />
<path
id="path3638"
d="m 195.92471,369.36762 1.27833,-2.89248 -1.84647,-1.87621 v -6.41037 l 2.13055,-2.34526 h 44.45738 l 1.70443,2.50161 2.41462,-1.87621 -2.48563,-2.73613 h -47.79524 l -2.37911,2.61887 v 10.28004 l 2.46788,2.56024 m -38.62501,49.36179 -4.64282,12.40054 52.41142,-57.84966 v -6.87942 z"
style="fill:#478cbf;fill-opacity:1;stroke:#000000;stroke-width:0.41726059px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
inkscape:connector-curvature="0" />
<path
id="path3642"
d="m 162.86589,357.7369 2.31001,-1.65835 v 10.06064 l -2.66153,2.92974 h -5.1724 v 49.58456 l -4.72044,12.27178 v -64.78608 h 8.6374 l 1.60696,-1.43724 z"
style="fill:#478cbf;fill-opacity:1;stroke:#000000;stroke-width:0.41726059px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
inkscape:connector-curvature="0" />
<path
d="m 197.06456,355.74729 -1.70266,1.87425 v 6.88137 l 1.49138,1.64168 h 7.87946 v 6.6488 l -52.12379,58.1565 v -64.72321 h 8.66244 l 1.77723,-1.95634 v -6.96346 l -1.64052,-1.39542 h -45.58657 l -1.49138,1.64168 v 7.11394 l 1.51624,1.66904 h 7.92918 v 119.18594 l 1.49138,1.64168 h 9.01043 L 243.50867,363.0938 v -5.47226 l -1.70266,-1.87425 z"
id="path3622"
style="fill:#478cbf;fill-opacity:1;stroke:#000000;stroke-width:0.41726059px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
inkscape:connector-curvature="0" />
<path
id="path3636"
d="m 243.64893,357.78205 2.426,-1.54181 v 9.67203 L 136.04072,489.68148 h -11.68216 l 1.11611,-2.44127 h 8.9483 L 243.5069,363.25432 Z"
style="fill:#478cbf;fill-opacity:1;stroke:#000000;stroke-width:0.41726059px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
inkscape:connector-curvature="0" />
<path
id="path3652"
d="m 204.79746,366.30501 -2.46065,2.8192 h -6.42784 l 1.50652,-2.8192 c 0.0502,0 7.38197,0 7.38197,0 z"
style="fill:#478cbf;fill-opacity:1;stroke:#000000;stroke-width:0.41726059px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
inkscape:connector-curvature="0" />
<g
transform="matrix(0.90138601,0,0,0.99222542,-92.530288,-192.23791)"
id="g3673">
<path
style="fill:#cccccc;fill-opacity:1;stroke:#000000;stroke-width:8;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
id="path3671"
d="m 399.78125,560 a 1.2330102,1.2330102 0 0 0 -0.5625,0.28125 l -5.3125,4.5625 A 1.2330102,1.2330102 0 0 0 393.5625,565.375 L 388.25,580.25 a 1.2330102,1.2330102 0 0 0 0.28125,1.28125 l 4.0625,4.0625 a 1.2330102,1.2330102 0 0 0 0.875,0.34375 H 409.875 a 1.2330102,1.2330102 0 0 0 0.875,-0.34375 l 4.28125,-4.3125 a 1.2330102,1.2330102 0 0 0 0.3125,-0.53125 l 4.5625,-15.65625 a 1.2330102,1.2330102 0 0 0 -0.3125,-1.21875 l -3.53125,-3.53125 A 1.2330102,1.2330102 0 0 0 415.1875,560 h -15.15625 a 1.2330102,1.2330102 0 0 0 -0.25,0 z m -30.0625,41.9375 a 1.2330102,1.2330102 0 0 0 -0.9375,0.90625 l -2.03125,8.0625 a 1.2330102,1.2330102 0 0 0 1.1875,1.53125 h 9.65625 l -23.9375,68.34375 a 1.2330102,1.2330102 0 0 0 1.15625,1.625 h 34.84375 a 1.2330102,1.2330102 0 0 0 1.1875,-0.84375 l 2.28125,-7.34375 a 1.2330102,1.2330102 0 0 0 -1.1875,-1.59375 h -7.875 L 407.75,603.5625 a 1.2330102,1.2330102 0 0 0 -1.15625,-1.625 h -36.625 a 1.2330102,1.2330102 0 0 0 -0.25,0 z m 110.875,0.25 a 1.2330102,1.2330102 0 0 0 -0.6875,0.40625 l -7.25,8.1875 H 461.125 l -7.6875,-7.96875 a 1.2330102,1.2330102 0 0 0 -0.875,-0.375 H 425.03125 A 1.2330102,1.2330102 0 0 0 423.875,603.25 l -2.53125,7.5625 a 1.2330102,1.2330102 0 0 0 1.15625,1.625 h 7.375 l -22.9375,67.59375 a 1.2330102,1.2330102 0 0 0 1.15625,1.625 h 29.3125 a 1.2330102,1.2330102 0 0 0 1.15625,-0.8125 l 2.25,-6.59375 a 1.2330102,1.2330102 0 0 0 -1.15625,-1.625 h -5.125 l 14.625,-46.03125 H 475.625 l -16.6875,53.46875 a 1.2330102,1.2330102 0 0 0 1.1875,1.59375 h 28.28125 a 1.2330102,1.2330102 0 0 0 1.125,-0.75 l 2.53125,-6.0625 a 1.2330102,1.2330102 0 0 0 -1.125,-1.6875 h -5.125 l 14.875,-46.8125 h 25.1875 l -16.9375,53.71875 a 1.2330102,1.2330102 0 0 0 1.1875,1.59375 h 31.0625 a 1.2330102,1.2330102 0 0 0 1.15625,-0.78125 l 2.53125,-6.59375 a 1.2330102,1.2330102 0 0 0 -1.15625,-1.65625 h -6.15625 l 18.71875,-60.78125 a 1.2330102,1.2330102 0 0 0 -0.1875,-1.125 l -5.8125,-7.8125 a 1.2330102,1.2330102 0 0 0 -1,-0.46875 H 527.0625 a 1.2330102,1.2330102 0 0 0 -0.90625,0.375 l -7,7.6875 h -12.25 l -7.25,-7.9375 a 1.2330102,1.2330102 0 0 0 -0.90625,-0.375 h -17.90625 a 1.2330102,1.2330102 0 0 0 -0.25,0 z"
inkscape:connector-curvature="0" />
<path
d="m 400.03125,561.21875 -5.3125,4.5625 -5.3125,14.875 4.0625,4.0625 H 409.875 l 4.28125,-4.3125 4.5625,-15.65625 -3.53125,-3.53125 z m -30.0625,41.9375 -2.03125,8.0625 h 11.375 l -24.5,69.96875 h 34.84375 l 2.28125,-7.34375 h -9.59375 l 24.25,-70.6875 z m 110.875,0.25 L 473.25,612 h -12.625 l -8.0625,-8.34375 h -27.53125 l -2.53125,7.5625 h 9.09375 l -23.5,69.21875 h 29.3125 l 2.25,-6.59375 h -6.8125 L 448.25,625.375 h 29.0625 l -17.1875,55.0625 h 28.28125 l 2.53125,-6.0625 h -6.8125 l 15.65625,-49.25 h 27.78125 l -17.4375,55.3125 h 31.0625 l 2.53125,-6.59375 H 535.875 l 19.21875,-62.375 -5.8125,-7.8125 H 527.0625 l -7.34375,8.0625 h -13.375 l -7.59375,-8.3125 z"
id="path3665"
style="fill:#478cbf;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
inkscape:connector-curvature="0" />
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 14 KiB

View File

@ -1,7 +0,0 @@
[plugin]
name="godot-vim"
description="VIM bindings for godot4"
author="Josh N"
version="0.3"
script="godot-vim.gd"

View File

@ -1,86 +0,0 @@
extends LineEdit
const Cursor = preload("res://addons/godot_vim/cursor.gd")
const StatusBar = preload("res://addons/godot_vim/status_bar.gd")
const Constants = preload("res://addons/godot_vim/constants.gd")
const Dispatcher = preload("res://addons/godot_vim/dispatcher.gd")
const Mode = Constants.Mode
const Marks = preload("res://addons/godot_vim/commands/marks.gd")
const Goto = preload("res://addons/godot_vim/commands/goto.gd")
const Find = preload("res://addons/godot_vim/commands/find.gd")
var code_edit: CodeEdit
var cursor: Cursor
var status_bar: StatusBar
var globals: Dictionary
var dispatcher: Dispatcher
var is_paused: bool = false
var search_pattern: String = ''
func _ready():
dispatcher = Dispatcher.new()
dispatcher.globals = globals
placeholder_text = "Enter command..."
show()
text_submitted.connect(_on_text_submitted)
text_changed.connect(_on_text_changed)
editable = true
func set_command(cmd: String):
text = cmd
caret_column = text.length()
func _on_text_changed(cmd: String):
if !cmd.begins_with('/'): return
var pattern: String = cmd.substr(1)
var rmatch: RegExMatch = globals.vim_plugin.search_regex(
code_edit,
pattern,
cursor.get_caret_pos() + Vector2i.RIGHT
)
if rmatch == null:
code_edit.remove_secondary_carets()
return
var pos: Vector2i = globals.vim_plugin.idx_to_pos(code_edit, rmatch.get_start())
if code_edit.get_caret_count() < 2:
code_edit.add_caret(pos.y, pos.x)
code_edit.select(pos.y, pos.x, pos.y, pos.x + rmatch.get_string().length(), 1)
code_edit.scroll_vertical = code_edit.get_scroll_pos_for_line(pos.y)
func handle_command(cmd: String):
if cmd.begins_with('/'):
var find = Find.new()
find.execute(globals, cmd)
return
if cmd.trim_prefix(':').is_valid_int():
var goto = Goto.new()
goto.execute(globals, cmd.trim_prefix(':'))
return
if dispatcher.dispatch(cmd) == OK:
set_paused(true)
return
status_bar.display_error('Unknown command: "%s"' % [ cmd.trim_prefix(':') ])
set_paused(true)
func close():
hide()
clear()
set_paused(false)
func set_paused(paused: bool):
is_paused = paused
text = "Press ENTER to continue" if is_paused else ""
editable = !is_paused
func _on_text_submitted(new_text: String):
if is_paused:
cursor.set_mode(Mode.NORMAL)
status_bar.main_label.text = ''
return
handle_command(new_text)

View File

@ -1 +0,0 @@
uid://lk5et75ba1pr

View File

@ -1,16 +0,0 @@
const Constants = preload("res://addons/godot_vim/constants.gd")
const Mode = Constants.Mode
func execute(api : Dictionary, args: String):
api.command_line.search_pattern = args.substr(1)
var rmatch: RegExMatch = api.vim_plugin.search_regex(
api.code_edit,
api.command_line.search_pattern,
api.cursor.get_caret_pos() + Vector2i.RIGHT
)
if rmatch != null:
var pos: Vector2i = api.vim_plugin.idx_to_pos(api.code_edit, rmatch.get_start())
api.cursor.set_caret_pos(pos.y, pos.x)
else:
api.status_bar.display_error('Pattern not found: "%s"' % [api.command_line.search_pattern])
api.cursor.set_mode(Mode.NORMAL)

View File

@ -1 +0,0 @@
uid://dp7ck72w5b66n

View File

@ -1,6 +0,0 @@
const Constants = preload("res://addons/godot_vim/constants.gd")
const Mode = Constants.Mode
func execute(api, args):
api.cursor.set_caret_pos(args.to_int(), 0)
api.cursor.set_mode(Mode.NORMAL)

View File

@ -1 +0,0 @@
uid://cu4md7kr2qrp

View File

@ -1,29 +0,0 @@
const Contants = preload("res://addons/godot_vim/constants.gd")
const StatusBar = preload("res://addons/godot_vim/status_bar.gd")
const Mode = Contants.Mode
func execute(api, _args):
var marks: Dictionary = api.get('marks', {})
if marks.is_empty():
api.status_bar.display_error("No marks set")
api.cursor.set_mode(Mode.NORMAL)
return
var display_mark = func(key: String, m: Dictionary) -> String:
var pos: Vector2i = m.get('pos', Vector2i())
var file: String = m.get('file', '')
return "\n%s\t\t%s \t%s \t\t %s" % [key, pos.y, pos.x, file]
var text: String = "[color=%s]List of all marks[/color]\nmark\tline\tcol \t file" % StatusBar.SPECIAL_COLOR
for key in marks.keys():
var unicode: int = key.unicode_at(0)
if (unicode < 65 or unicode > 90) and (unicode < 97 or unicode > 122):
continue
text += display_mark.call(key, marks[key])
for key in marks.keys():
var unicode: int = key.unicode_at(0)
if (unicode >= 65 and unicode <= 90) or (unicode >= 97 and unicode <= 122) or key == "-1":
continue
text += display_mark.call(key, marks[key])
api.status_bar.display_text(text, Control.TEXT_DIRECTION_LTR)

View File

@ -1 +0,0 @@
uid://cf1an2q01i3ix

View File

@ -1,8 +0,0 @@
enum Mode { NORMAL, INSERT, VISUAL, VISUAL_LINE, COMMAND }
# Used for commands like "w" "b" and "e" respectively
enum WordEdgeMode { WORD, BEGINNING, END }
const SPACES: String = " \t"
const KEYWORDS: String = ".,\"'-=+!@#$%^&*()[]{}?~/\\<>:;"
const DIGITS: String = "0123456789"

View File

@ -1 +0,0 @@
uid://d2ro7q1ec5gk0

View File

@ -1,722 +0,0 @@
extends Control
const CommandLine = preload("res://addons/godot_vim/command_line.gd")
const StatusBar = preload("res://addons/godot_vim/status_bar.gd")
const Constants = preload("res://addons/godot_vim/constants.gd")
const Mode = Constants.Mode
const WordEdgeMode = Constants.WordEdgeMode
const KEYWORDS = Constants.KEYWORDS
const SPACES = Constants.SPACES
var code_edit: CodeEdit
var command_line: CommandLine
var status_bar: StatusBar
var mode: Mode = Mode.NORMAL
var caret: Vector2
var input_stream: String = ""
var selection_from: Vector2i = Vector2i() # For visual modes
var selection_to: Vector2i = Vector2i() # For visual modes
var globals: Dictionary = {}
func _init():
set_focus_mode(FOCUS_ALL)
func _ready():
code_edit.connect("focus_entered", focus_entered)
code_edit.connect("caret_changed", cursor_changed)
call_deferred('set_mode', Mode.NORMAL)
func cursor_changed():
draw_cursor()
func focus_entered():
if mode == Mode.NORMAL:
code_edit.release_focus()
self.grab_focus()
func reset_normal():
code_edit.cancel_code_completion()
input_stream = ''
set_mode(Mode.NORMAL)
selection_from = Vector2i.ZERO
selection_to = Vector2i.ZERO
set_column(code_edit.get_caret_column())
return
func back_to_normal_mode(event, m):
var old_caret_pos = code_edit.get_caret_column()
if Input.is_key_pressed(KEY_ESCAPE):
if m == Mode.INSERT:
handle_input_stream('l')
reset_normal()
return 1
if m == Mode.INSERT:
var old_time = Time.get_ticks_msec()
if Input.is_key_label_pressed(KEY_J):
old_caret_pos = code_edit.get_caret_column()
if Time.get_ticks_msec() - old_time < 700 and Input.is_key_label_pressed(KEY_K):
code_edit.backspace()
code_edit.cancel_code_completion()
reset_normal()
handle_input_stream('l')
return 1
return 0
func _input(event):
if back_to_normal_mode(event, mode): return
draw_cursor()
code_edit.cancel_code_completion()
if !has_focus(): return
if !event is InputEventKey: return
if !event.pressed: return
if mode == Mode.INSERT or mode == Mode.COMMAND: return
if event.keycode == KEY_ESCAPE:
input_stream = ''
return
var ch: String
if !event is InputEventMouseMotion and !event is InputEventMouseButton:
ch = char(event.unicode)
if Input.is_key_pressed(KEY_ENTER):
ch = '<CR>'
if Input.is_key_pressed(KEY_TAB):
ch = '<TAB>'
if Input.is_key_pressed(KEY_CTRL):
if OS.is_keycode_unicode(event.keycode):
var c: String = char(event.keycode)
if !Input.is_key_pressed(KEY_SHIFT):
c = c.to_lower()
ch = '<C-%s>' % c
input_stream += ch
status_bar.display_text(input_stream)
var s: int = globals.vim_plugin.get_first_non_digit_idx(input_stream)
if s == -1: return # All digits
var cmd: String = input_stream.substr(s)
var count: int = maxi( input_stream.left(s).to_int(), 1 )
for i in count:
input_stream = handle_input_stream(cmd)
func handle_input_stream(stream: String) -> String:
# BEHOLD, THE IF STATEMENT HELL!!! MUAHAHAHAHa
if stream == 'h':
move_column(-1)
return ''
if stream == 'j':
move_line(+1)
return ''
if stream == 'k':
move_line(-1)
return ''
if stream == 'l':
move_column(+1)
return ''
if stream.to_lower().begins_with('w'):
var p: Vector2i = get_word_edge_pos(get_line(), get_column(), '' if stream[0] == 'W' else KEYWORDS, WordEdgeMode.WORD)
set_caret_pos(p.y, p.x)
return ''
if stream.to_lower().begins_with('e'):
var p: Vector2i = get_word_edge_pos(get_line(), get_column(), '' if stream[0] == 'E' else KEYWORDS, WordEdgeMode.END)
set_caret_pos(p.y, p.x)
return ''
if stream.to_lower().begins_with('b'):
var p: Vector2i = get_word_edge_pos(get_line(), get_column(), '' if stream[0] == 'B' else KEYWORDS, WordEdgeMode.BEGINNING)
set_caret_pos(p.y, p.x)
return ''
if stream.to_lower() .begins_with('f') or stream.to_lower() .begins_with('t'):
if stream.length() == 1: return stream
var char: String = stream[1] # TODO check for <TAB>, <CR> and <Ctrl-somethign>
globals.last_search = stream.left(2) # First 2 in case it's longer
var col: int = find_char_motion(get_line(), get_column(), stream[0], char)
if col >= 0:
set_column(col)
return ''
if stream.begins_with(';') and globals.has('last_search'):
var cmd: String = globals.last_search[0]
var col: int = find_char_motion(get_line(), get_column(), cmd, globals.last_search[1])
if col >= 0:
set_column(col)
return ''
if stream.begins_with(',') and globals.has('last_search'):
var cmd: String = globals.last_search[0]
cmd = cmd.to_upper() if is_lowercase(cmd) else cmd.to_lower()
var col: int = find_char_motion(get_line(), get_column(), cmd, globals.last_search[1])
if col >= 0:
set_column(col)
return ''
if mode == Mode.VISUAL: # TODO make it work for visual line too
var range: Array = calc_double_motion_region(selection_to, stream)
if range.size() == 1: return stream
if range.size() == 2:
selection_from = range[0]
selection_to = range[1]
update_visual_selection()
if stream.begins_with('J') and mode == Mode.NORMAL:
code_edit.begin_complex_operation()
code_edit.select( get_line(), get_line_length(), get_line()+1, code_edit.get_first_non_whitespace_column(get_line()+1) )
code_edit.delete_selection()
code_edit.deselect()
code_edit.insert_text_at_caret(' ')
code_edit.end_complex_operation()
globals.last_command = stream
return ''
if stream.begins_with('d'):
if is_mode_visual(mode):
DisplayServer.clipboard_set( '\r' + code_edit.get_selected_text() )
code_edit.delete_selection()
move_line(+1)
set_mode(Mode.NORMAL)
return ''
if stream.begins_with('dd') and mode == Mode.NORMAL:
code_edit.select( get_line()-1, get_line_length(get_line()-1), get_line(), get_line_length() )
DisplayServer.clipboard_set( '\r' + code_edit.get_selected_text() )
code_edit.delete_selection()
move_line(+1)
globals.last_command = stream
return ''
var range: Array = calc_double_motion_region(get_caret_pos(), stream, 1)
if range.size() == 0: return ''
if range.size() == 1: return stream
if range.size() == 2:
code_edit.select(range[0].y, range[0].x, range[1].y, range[1].x + 1)
code_edit.cut()
globals.last_command = stream
return ''
if mode == Mode.NORMAL and stream.begins_with('D'):
code_edit.select( get_line(), code_edit.get_caret_column(), get_line(), get_line_length() )
code_edit.cut()
globals.last_command = stream
return ''
if stream.begins_with('p'):
code_edit.begin_complex_operation()
if is_mode_visual(mode):
code_edit.delete_selection()
if DisplayServer.clipboard_get().begins_with('\r\n'):
set_column(get_line_length())
else:
move_column(+1)
code_edit.deselect()
code_edit.paste()
move_column(-1)
code_edit.end_complex_operation()
set_mode(Mode.NORMAL)
globals.last_command = stream
return ''
if stream.begins_with('P'):
status_bar.display_error("Unimplemented command: P")
return ''
if stream.begins_with('$'):
set_column(get_line_length())
return ''
if stream.begins_with('^'):
set_column( code_edit.get_first_non_whitespace_column(get_line()) )
return ''
if stream == 'G':
set_line(code_edit.get_line_count())
return ''
if stream.begins_with('g'):
if stream.begins_with('gg'):
set_line(0)
return ''
if stream.begins_with('gc') and is_mode_visual(mode):
code_edit.begin_complex_operation()
for line in range( min(selection_from.y, selection_to.y), max(selection_from.y, selection_to.y)+1 ):
toggle_comment(line)
code_edit.end_complex_operation()
set_mode(Mode.NORMAL)
return ''
if stream.begins_with('gcc') and mode == Mode.NORMAL:
toggle_comment(get_line())
globals.last_command = stream
return ''
return stream
if stream == '0':
set_column(0)
return ''
if stream == 'i' and mode == Mode.NORMAL:
set_mode(Mode.INSERT)
return ''
if stream == 'a' and mode == Mode.NORMAL:
set_mode(Mode.INSERT)
move_column(+1)
return ''
if stream == 'I' and mode == Mode.NORMAL:
set_column(code_edit.get_first_non_whitespace_column(get_line()))
set_mode(Mode.INSERT)
return ''
if stream.begins_with('A') and mode == Mode.NORMAL:
set_mode(Mode.INSERT)
set_column(get_line_length())
return ''
if stream == 'v':
set_mode(Mode.VISUAL)
return ''
if stream == 'V':
set_mode(Mode.VISUAL_LINE)
return ''
if stream.begins_with('o'):
if is_mode_visual(mode):
var tmp: Vector2i = selection_from
selection_from = selection_to
selection_to = tmp
return ''
var ind: int = code_edit.get_first_non_whitespace_column(get_line())
if code_edit.get_line(get_line()).ends_with(':'):
ind += 1
var line: int = code_edit.get_caret_line()
code_edit.insert_line_at(line + int(line < code_edit.get_line_count() - 1), "\t".repeat(ind))
move_line(+1)
set_column(ind)
set_mode(Mode.INSERT)
globals.last_command = stream
return ''
if stream.begins_with('O') and mode == Mode.NORMAL:
var ind: int = code_edit.get_first_non_whitespace_column(get_line())
code_edit.insert_line_at(get_line(), "\t".repeat(ind))
move_line(-1)
set_column(ind)
set_mode(Mode.INSERT)
globals.last_command = stream
return ''
if stream == 'x':
code_edit.copy()
code_edit.delete_selection()
globals.last_command = stream
return ''
if stream.begins_with('s'):
code_edit.cut()
set_mode(Mode.INSERT)
return ''
if stream == 'u':
code_edit.undo()
set_mode(Mode.NORMAL)
return ''
if stream.begins_with('<C-r>'):
code_edit.redo()
return ''
if stream.begins_with('r') and mode == Mode.NORMAL:
if stream.length() < 2: return stream
code_edit.begin_complex_operation()
code_edit.delete_selection()
var ch: String = stream[1]
if stream.substr(1).begins_with('<CR>'):
ch = '\n'
elif stream.substr(1).begins_with('<TAB>'):
ch = '\t'
code_edit.insert_text_at_caret(ch)
move_column(-1)
code_edit.end_complex_operation()
globals.last_command = stream
return ''
if stream.begins_with('y'):
if is_mode_visual(mode):
code_edit.copy()
set_mode(Mode.NORMAL)
return ''
if stream.length() == 1: return stream
if stream.begins_with('yy') and mode == Mode.NORMAL:
code_edit.select(code_edit.get_caret_line(), 0, code_edit.get_caret_line(), get_line_length())
DisplayServer.clipboard_set( '\r\n' + code_edit.get_selected_text() )
move_column(0)
code_edit.deselect()
var range: Array = calc_double_motion_region(get_caret_pos(), stream, 1)
if range.size() == 0: return ''
if range.size() == 1: return stream
if range.size() == 2:
code_edit.select(range[0].y, range[0].x, range[1].y, range[1].x + 1)
code_edit.copy()
code_edit.deselect()
return ''
if stream == '.':
if globals.has('last_command'):
handle_input_stream(globals.last_command)
call_deferred(&'set_mode', Mode.NORMAL)
return ''
if stream.begins_with(':') and mode == Mode.NORMAL: # Could make this work with visual too ig
set_mode(Mode.COMMAND)
command_line.set_command(':')
return ''
if stream.begins_with('/') and mode == Mode.NORMAL:
set_mode(Mode.COMMAND)
command_line.set_command('/')
return ''
if stream.begins_with('n'):
var rmatch: RegExMatch = globals.vim_plugin.search_regex(
code_edit,
command_line.search_pattern,
get_caret_pos() + Vector2i.RIGHT
)
if rmatch != null:
var pos: Vector2i = globals.vim_plugin.idx_to_pos(code_edit,rmatch.get_start())
set_caret_pos(pos.y, pos.x)
return ''
if stream.begins_with('N'):
var rmatch: RegExMatch = globals.vim_plugin.search_regex_backwards(
code_edit,
command_line.search_pattern,
get_caret_pos() + Vector2i.LEFT
)
if rmatch != null:
var pos: Vector2i = globals.vim_plugin.idx_to_pos(code_edit,rmatch.get_start())
set_caret_pos(pos.y, pos.x)
return ''
if stream.begins_with('c'):
if mode == Mode.VISUAL:
code_edit.cut()
set_mode(Mode.INSERT)
return ''
if stream.begins_with('cc') and mode == Mode.NORMAL:
code_edit.begin_complex_operation()
var l: int = get_line()
var ind: int = code_edit.get_first_non_whitespace_column(l)
code_edit.select( l-1, get_line_length(l-1), l, get_line_length(l) )
code_edit.cut()
code_edit.insert_line_at(get_line()+1, "\t".repeat(ind))
code_edit.end_complex_operation()
move_line(+1)
set_mode(Mode.INSERT)
globals.last_command = stream
return ''
var range: Array = calc_double_motion_region(get_caret_pos(), stream, 1)
if range.size() == 0: return ''
if range.size() == 1: return stream
if range.size() == 2:
code_edit.select(range[0].y, range[0].x, range[1].y, range[1].x + 1)
code_edit.cut()
set_mode(Mode.INSERT)
globals.last_command = stream
return ''
if mode == Mode.NORMAL and stream.begins_with('C'):
code_edit.select( get_line(), code_edit.get_caret_column(), get_line(), get_line_length() )
code_edit.cut()
set_mode(Mode.INSERT)
globals.last_command = stream
return ''
if stream.begins_with('z'):
if stream.begins_with('zz') and mode == Mode.NORMAL:
code_edit.center_viewport_to_caret()
return ''
return stream
if stream.begins_with('>'):
if is_mode_visual(mode) and stream.length() == 1:
code_edit.indent_lines()
return ''
if stream.length() == 1: return stream
if stream.begins_with('>>') and mode == Mode.NORMAL:
code_edit.indent_lines()
globals.last_command = stream
return ''
if stream.begins_with('<'):
if is_mode_visual(mode) and stream.length() == 1:
code_edit.unindent_lines()
return ''
if stream.length() == 1: return stream
if stream.begins_with('<<') and mode == Mode.NORMAL:
code_edit.unindent_lines()
globals.last_command = stream
return ''
if stream.begins_with('}'):
var para_edge: Vector2i = get_paragraph_edge_pos( get_line(), 1 )
set_caret_pos(para_edge.y, para_edge.x)
return ''
if stream.begins_with('{'):
var para_edge: Vector2i = get_paragraph_edge_pos( get_line(), -1 )
set_caret_pos(para_edge.y, para_edge.x)
return ''
if stream.begins_with('m') and mode == Mode.NORMAL:
if stream.length() < 2: return stream
if !globals.has('marks'): globals.marks = {}
var m: String = stream[1]
var unicode: int = m.unicode_at(0)
if (unicode < 65 or unicode > 90) and (unicode < 97 or unicode > 122):
status_bar.display_error('Marks must be between a-z or A-Z')
return ''
globals.marks[m] = {
'file' : globals.script_editor.get_current_script().resource_path,
'pos' : Vector2i(code_edit.get_caret_column(), code_edit.get_caret_line())
}
status_bar.display_text('Mark "%s" set' % m, TEXT_DIRECTION_LTR)
return ''
if stream.begins_with('`'):
if stream.length() < 2: return stream
if !globals.has('marks'): globals.marks = {}
if !globals.marks.has(stream[1]):
status_bar.display_error('Mark "%s" not set' % [ stream[1] ])
return ''
var mark: Dictionary = globals.marks[stream[1]]
globals.vim_plugin.edit_script(mark.file, mark.pos)
return ''
return ''
# Mostly used for commands like "w", "b", and "e"
# delims is the keywords / characters used as delimiters. Usually, it's the constant KEYWORDS
func get_word_edge_pos(from_line: int, from_col: int, delims: String, mode: WordEdgeMode) -> Vector2i:
var search_dir: int = -1 if mode == WordEdgeMode.BEGINNING else 1
var char_offset: int = 1 if mode == WordEdgeMode.END else -1
var line: int = from_line
var col: int = from_col + search_dir
var text: String = get_line_text(line)
while line >= 0 and line < code_edit.get_line_count():
while col >= 0 and col < text.length():
var char: String = text[col]
if SPACES.contains(char):
col += search_dir
continue
# Please don't question this lmao. It just works, alight?
var other_char: String = ' ' if col == (text.length()-1) * int(char_offset > 0) else text[col + char_offset]
if SPACES.contains(other_char):
return Vector2i(col, line)
if delims.contains(char) != delims.contains(other_char):
return Vector2i(col, line)
col += search_dir
line += search_dir
text = get_line_text(line)
col = (text.length() - 1) * int(search_dir < 0 and char_offset < 0)
return Vector2i(from_col, from_line)
func get_paragraph_edge_pos(from_line: int, search_dir: int):
var line: int = from_line
var prev_empty: bool = code_edit.get_line(line) .strip_edges().is_empty()
line += search_dir
while line >= 0 and line < code_edit.get_line_count():
var text: String = code_edit.get_line(line) .strip_edges()
if text.is_empty() and !prev_empty:
return Vector2i(text.length(), line)
prev_empty = text.is_empty()
line += search_dir
return Vector2i(0, line)
# motion: command like "f", "t", "F", or "T"
func find_char_motion(in_line: int, from_col: int, motion: String, char: String) -> int:
var search_dir: int = 1 if is_lowercase(motion) else -1
var offset: int = int(motion == 'T') - int(motion == 't') # 1 if T, -1 if t, 0 otherwise
var text: String = get_line_text(in_line)
var col: int = -1
if motion == 'f' or motion == 't':
col = text.find(char, from_col + search_dir)
elif motion == 'F' or motion == 'T':
col = text.rfind(char, from_col + search_dir)
if col == -1:
return -1
return col + offset
# returns: [ Vector2i from_pos, Vector2i to_pos ]
func calc_double_motion_region(from_pos: Vector2i, stream: String, from_char: int = 0) -> Array[Vector2i]:
var primary: String = get_stream_char(stream, from_char)
var secondary: String = get_stream_char(stream, from_char + 1)
if primary == '':
return [from_pos] # Incomplete
if primary.to_lower() == 'w':
var p1: Vector2i = get_word_edge_pos(from_pos.y, from_pos.x, '' if primary == 'W' else KEYWORDS, WordEdgeMode.WORD)
return [from_pos, p1 + Vector2i.LEFT]
if primary.to_lower() == 'b':
var p0: Vector2i = get_word_edge_pos(from_pos.y, from_pos.x, '' if primary == 'B' else KEYWORDS, WordEdgeMode.BEGINNING)
return [p0, from_pos + Vector2i.LEFT]
if primary.to_lower() == 'e':
var p1: Vector2i = get_word_edge_pos(from_pos.y, from_pos.x, '' if primary == 'E' else KEYWORDS, WordEdgeMode.END)
return [from_pos, p1]
if primary == '$':
var p1: Vector2i = Vector2i(get_line_length(from_pos.y), from_pos.y)
return [from_pos, p1]
if primary == '^':
var p0: Vector2i = Vector2i(code_edit.get_first_non_whitespace_column(from_pos.y), from_pos.y)
return [p0, from_pos + Vector2i.LEFT]
if primary != 'i' and primary != 'a':
return [] # Invalid
if secondary == '':
return [from_pos] # Incomplete
if primary == 'i' and secondary.to_lower() == 'w':
var p0: Vector2i = get_word_edge_pos(from_pos.y, from_pos.x + 1, '' if secondary == 'W' else KEYWORDS, WordEdgeMode.BEGINNING)
var p1: Vector2i = get_word_edge_pos(from_pos.y, from_pos.x - 1, '' if secondary == 'W' else KEYWORDS, WordEdgeMode.END)
return [ p0, p1 ]
if primary == 'i' and secondary == 'p':
var p0: Vector2i = get_paragraph_edge_pos(from_pos.y + 1, -1) + Vector2i.DOWN
var p1: Vector2i = get_paragraph_edge_pos(from_pos.y - 1, 1)
return [ p0, p1 ]
return [] # Unknown combination
func toggle_comment(line: int):
var ind: int = code_edit.get_first_non_whitespace_column(line)
var text: String = get_line_text(line)
# Comment line
if text[ind] != '#':
code_edit.set_line(line, text.insert(ind, '# '))
return
# Uncomment line
var start_col: int = get_word_edge_pos(line, ind, KEYWORDS, WordEdgeMode.WORD).x
code_edit.select(line, ind, line, start_col)
code_edit.delete_selection()
func set_mode(m: int):
var old_mode: int = mode
mode = m
command_line.close()
match mode:
Mode.NORMAL:
code_edit.remove_secondary_carets()
code_edit.deselect()
code_edit.release_focus()
code_edit.deselect()
self.grab_focus()
status_bar.set_mode_text(Mode.NORMAL)
if old_mode == Mode.INSERT:
move_column(-1)
Mode.VISUAL:
if old_mode != Mode.VISUAL_LINE:
selection_from = Vector2i(code_edit.get_caret_column(), code_edit.get_caret_line())
selection_to = Vector2i(code_edit.get_caret_column(), code_edit.get_caret_line())
set_caret_pos(selection_to.y, selection_to.x)
status_bar.set_mode_text(Mode.VISUAL)
Mode.VISUAL_LINE:
if old_mode != Mode.VISUAL:
selection_from = Vector2i(code_edit.get_caret_column(), code_edit.get_caret_line())
selection_to = Vector2i(code_edit.get_caret_column(), code_edit.get_caret_line())
set_caret_pos(selection_to.y, selection_to.x)
status_bar.set_mode_text(Mode.VISUAL_LINE)
Mode.COMMAND:
command_line.show()
command_line.call_deferred("grab_focus")
status_bar.set_mode_text(Mode.COMMAND)
Mode.INSERT:
code_edit.call_deferred("grab_focus")
status_bar.set_mode_text(Mode.INSERT)
_:
pass
func move_line(offset:int):
set_line(get_line() + offset)
func get_line() -> int:
if is_mode_visual(mode):
return selection_to.y
return code_edit.get_caret_line()
func get_line_text(line: int = -1) -> String:
if line == -1:
return code_edit.get_line(get_line())
return code_edit.get_line(line)
func get_line_length(line: int = -1) -> int:
return get_line_text(line).length()
func set_caret_pos(line: int, column: int):
set_line(line) # line has to be set before column
set_column(column)
func get_caret_pos() -> Vector2i:
return Vector2i(code_edit.get_caret_column(), code_edit.get_caret_line())
func set_line(position:int):
if !is_mode_visual(mode):
code_edit.set_caret_line(min(position, code_edit.get_line_count()-1))
return
selection_to = Vector2i( clampi(selection_to.x, 0, get_line_length(position)), clampi(position, 0, code_edit.get_line_count()) )
update_visual_selection()
func move_column(offset: int):
set_column(get_column()+offset)
func get_column():
if is_mode_visual(mode):
return selection_to.x
return code_edit.get_caret_column()
func set_column(position: int):
if !is_mode_visual(mode):
var line: String = code_edit.get_line(code_edit.get_caret_line())
code_edit.set_caret_column(min(line.length(), position))
return
selection_to = Vector2i( clampi(position, 0, get_line_length(selection_to.y)), clampi(selection_to.y, 0, code_edit.get_line_count()) )
update_visual_selection()
func update_visual_selection():
if mode == Mode.VISUAL:
var to_right: bool = selection_to.x >= selection_from.x or selection_to.y > selection_from.y
code_edit.select( selection_from.y, selection_from.x + int(!to_right), selection_to.y, selection_to.x + int(to_right) )
elif mode == Mode.VISUAL_LINE:
var f: int = mini(selection_from.y, selection_to.y) - 1
var t: int = maxi(selection_from.y, selection_to.y)
code_edit.select(f, get_line_length(f), t, get_line_length(t))
func is_mode_visual(m: int) -> bool:
return m == Mode.VISUAL or m == Mode.VISUAL_LINE
func is_lowercase(text: String) -> bool:
return text == text.to_lower()
func is_uppercase(text: String) -> bool:
return text == text.to_upper()
func get_stream_char(stream: String, idx: int) -> String:
return stream[idx] if stream.length() > idx else ''
func draw_cursor():
if code_edit.is_dragging_cursor():
selection_from = Vector2i(code_edit.get_selection_from_column(), code_edit.get_selection_from_line())
selection_to = Vector2i(code_edit.get_selection_to_column(), code_edit.get_selection_to_line())
if code_edit.get_selected_text(0).length() > 1 and !is_mode_visual(mode):
code_edit.release_focus()
self.grab_focus()
set_mode(Mode.VISUAL)
if mode == Mode.INSERT:
if code_edit.has_selection(0):
code_edit.deselect(0)
return
if mode != Mode.NORMAL:
return
var line: int = code_edit.get_caret_line()
var column: int = code_edit.get_caret_column()
if column >= code_edit.get_line(line).length():
column -= 1
code_edit.set_caret_column(column)
code_edit.select(line, column, line, column+1)

View File

@ -1 +0,0 @@
uid://bmkia3drpjivh

View File

@ -1,22 +0,0 @@
extends Object
var handlers = {
"goto": preload("res://addons/godot_vim/commands/goto.gd"),
"find": preload("res://addons/godot_vim/commands/find.gd"),
"marks": preload("res://addons/godot_vim/commands/marks.gd")
}
var globals
func dispatch(command : String):
var command_idx_end = command.find(' ', 1)
if command_idx_end == -1: command_idx_end = command.length()
var handler_name = command.substr(1, command_idx_end-1)
if not handlers.has(handler_name):
return ERR_DOES_NOT_EXIST
var handler = handlers.get(handler_name)
var handler_instance = handler.new()
var args = command.substr(command_idx_end, command.length())
handler_instance.execute(globals, args)
return OK

View File

@ -1 +0,0 @@
uid://dvfyfj3wtqfds

View File

@ -1,7 +0,0 @@
[plugin]
name="GodotVim"
description=""
author="Bernardo Bruning"
version="0.1"
script="plugin.gd"

View File

@ -1,164 +0,0 @@
@tool
extends EditorPlugin
enum Mode { NORMAL, INSERT, VISUAL, VISUAL_LINE, COMMAND }
# Used for commands like "w" "b" and "e" respectively
enum WordEdgeMode { WORD, BEGINNING, END }
const SPACES: String = " \t"
const KEYWORDS: String = ".,\"'-=+!@#$%^&*()[]{}?~/\\<>:;"
const DIGITS: String = "0123456789"
const StatusBar = preload("res://addons/godot_vim/status_bar.gd")
const CommandLine = preload("res://addons/godot_vim/command_line.gd")
const Cursor = preload("res://addons/godot_vim/cursor.gd")
var cursor: Cursor
var command_line: CommandLine
var status_bar: StatusBar
var globals: Dictionary = {}
func _enter_tree():
globals = {}
if get_code_edit() != null:
_load()
get_editor_interface().get_script_editor().connect("editor_script_changed", _script_changed)
func _script_changed(script: Script):
# Add to recent files
var path: String = script.resource_path
var marks: Dictionary = globals.get('marks', {})
for i in range(9, -1, -1):
var m: String = str(i)
var pm: String = str(i - 1)
if !marks.has(pm):
continue
marks[m] = marks[pm]
marks['-1'] = { 'file' : path, 'pos' : Vector2i(-1, 0) }
_load()
func edit_script(path: String, pos: Vector2i):
var script = load(path)
var editor_interface: EditorInterface = globals.editor_interface
if script == null:
status_bar.display_error('Could not open file "%s"' % path)
return ''
editor_interface.edit_script(script)
cursor.call_deferred('set_caret_pos', pos.y, pos.x)
func _load():
if globals == null:
globals = {}
# Cursor
if cursor != null:
cursor.queue_free()
cursor = Cursor.new()
var code_edit = get_code_edit()
code_edit.select(code_edit.get_caret_line(), code_edit.get_caret_column(), code_edit.get_caret_line(), code_edit.get_caret_column()+1)
cursor.code_edit = code_edit
cursor.globals = globals
# Command line
if command_line != null:
command_line.queue_free()
command_line = CommandLine.new()
command_line.code_edit = code_edit
cursor.command_line = command_line
command_line.cursor = cursor
command_line.globals = globals
command_line.hide()
# Status bar
if status_bar != null:
status_bar.queue_free()
status_bar = StatusBar.new()
cursor.status_bar = status_bar
command_line.status_bar = status_bar
var editor_interface = get_editor_interface()
if editor_interface == null: return
var script_editor = editor_interface.get_script_editor()
if script_editor == null: return
var script_editor_base = script_editor.get_current_editor()
if script_editor_base == null: return
globals.editor_interface = editor_interface
globals.command_line = command_line
globals.status_bar = status_bar
globals.code_edit = code_edit
globals.cursor = cursor
globals.script_editor = script_editor
globals.vim_plugin = self
script_editor_base.add_child(cursor)
script_editor_base.add_child(status_bar)
script_editor_base.add_child(command_line)
func get_code_edit():
var editor = get_editor_interface().get_script_editor().get_current_editor()
return _select(editor, ['VSplitContainer', 'CodeTextEditor', 'CodeEdit'])
func _select(obj: Node, types: Array[String]): # ???
for type in types:
for child in obj.get_children():
if child.is_class(type):
obj = child
continue
return obj
func _exit_tree():
if cursor != null:
cursor.queue_free()
if command_line != null:
command_line.queue_free()
if status_bar != null:
status_bar.queue_free()
# -------------------------------------------------------------
# ** UTIL **
# -------------------------------------------------------------
func search_regex(text_edit: TextEdit, pattern: String, from_pos: Vector2i) -> RegExMatch:
var regex: RegEx = RegEx.new()
var err: int = regex.compile(pattern)
var idx: int = pos_to_idx(text_edit, from_pos)
var res: RegExMatch = regex.search(text_edit.text, idx)
if res == null:
return regex.search(text_edit.text, 0)
return res
func search_regex_backwards(text_edit: TextEdit, pattern: String, from_pos: Vector2i) -> RegExMatch:
var regex: RegEx = RegEx.new()
var err: int = regex.compile(pattern)
var idx: int = pos_to_idx(text_edit, from_pos)
# We use pop_back() so it doesn't print an error
var res: RegExMatch = regex.search_all(text_edit.text, 0, idx).pop_back()
if res == null:
return regex.search_all(text_edit.text).pop_back()
return res
func pos_to_idx(text_edit: TextEdit, pos: Vector2i) -> int:
text_edit.select(0, 0, pos.y, pos.x)
var len: int = text_edit.get_selected_text().length()
text_edit.deselect()
return len
func idx_to_pos(text_edit: TextEdit, idx: int) -> Vector2i:
var line: int = text_edit.text .count('\n', 0, idx)
var col: int = idx - text_edit.text .rfind('\n', idx) - 1
return Vector2i(col, line)
func get_first_non_digit_idx(str: String) -> int:
if str.is_empty(): return -1
if str[0] == '0': return 0 # '0...' is an exception
for i in str.length():
if !DIGITS.contains(str[i]):
return i
return -1 # All digits

View File

@ -1 +0,0 @@
uid://duaf0qcswso06

View File

@ -1,68 +0,0 @@
extends HBoxContainer
const ERROR_COLOR: String = "#ff8866"
const SPECIAL_COLOR: String = "#fcba03"
const Constants = preload("res://addons/godot_vim/constants.gd")
const Mode = Constants.Mode
var mode_label: Label
var main_label: RichTextLabel
func _ready():
var font = load("res://addons/godot_vim/hack_regular.ttf")
mode_label = Label.new()
mode_label.text = ''
mode_label.add_theme_color_override(&"font_color", Color.BLACK)
var stylebox: StyleBoxFlat = StyleBoxFlat.new()
stylebox.bg_color = Color.GOLD
stylebox.content_margin_left = 4.0
stylebox.content_margin_right = 4.0
stylebox.content_margin_top = 2.0
stylebox.content_margin_bottom = 2.0
mode_label.add_theme_stylebox_override(&"normal", stylebox)
mode_label.add_theme_font_override(&"font", font)
add_child(mode_label)
main_label = RichTextLabel.new()
main_label.bbcode_enabled = true
main_label.text = ''
main_label.fit_content = true
main_label.size_flags_horizontal = Control.SIZE_EXPAND_FILL
main_label.text_direction = Control.TEXT_DIRECTION_RTL
main_label.add_theme_font_override(&"normal_font", font)
add_child(main_label)
func display_text(text: String, text_direction: Control.TextDirection = TEXT_DIRECTION_RTL):
main_label.text = text
main_label.text_direction = text_direction
func display_error(text: String):
main_label.text = '[color=%s]%s' % [ERROR_COLOR, text]
main_label.text_direction = Control.TEXT_DIRECTION_LTR
func display_special(text: String):
main_label.text = '[color=%s]%s' % [SPECIAL_COLOR, text]
main_label.text_direction = Control.TEXT_DIRECTION_LTR
func set_mode_text(mode: Mode):
var stylebox: StyleBoxFlat = mode_label.get_theme_stylebox(&"normal")
match mode:
Mode.NORMAL:
mode_label.text = 'NORMAL'
stylebox.bg_color = Color.LIGHT_SALMON
Mode.INSERT:
mode_label.text = 'INSERT'
stylebox.bg_color = Color.POWDER_BLUE
Mode.VISUAL:
mode_label.text = 'VISUAL'
stylebox.bg_color = Color.PLUM
Mode.VISUAL_LINE:
mode_label.text = 'VISUAL LINE'
stylebox.bg_color = Color.PLUM
Mode.COMMAND:
mode_label.text = 'COMMAND'
stylebox.bg_color = Color.TOMATO
_:
pass

View File

@ -1 +0,0 @@
uid://bsixy362mx4r7