diff --git a/mesh_snap_utilities_line/__init__.py b/mesh_snap_utilities_line/__init__.py
index 1080cd9b645e6afa2b6b6bbef74d1d781c70eb41..7db590129f85d9441cb0d48d0876fc92ac7c68a8 100644
--- a/mesh_snap_utilities_line/__init__.py
+++ b/mesh_snap_utilities_line/__init__.py
@@ -22,7 +22,7 @@
 bl_info = {
     "name": "Snap_Utilities_Line",
     "author": "Germano Cavalcante",
-    "version": (5, 9, 6),
+    "version": (5, 9, 8),
     "blender": (2, 80, 0),
     "location": "View3D > TOOLS > Line Tool",
     "description": "Extends Blender Snap controls",
@@ -35,11 +35,13 @@ if "bpy" in locals():
     importlib.reload(widgets)
     importlib.reload(preferences)
     importlib.reload(op_line)
+    importlib.reload(keys)
 else:
     from . import navigation_ops
     from . import widgets
     from . import preferences
     from . import op_line
+    from . import keys
 
 import bpy
 from bpy.utils.toolsystem import ToolDef
@@ -65,7 +67,8 @@ def tool_line():
     icons_dir = os.path.join(os.path.dirname(__file__), "icons")
 
     return dict(
-        text="Make Line",
+        idname="snap_utilities.line",
+        label="Make Line",
         description=(
             "Make Lines\n"
             "Connect them to split faces"
@@ -73,7 +76,7 @@ def tool_line():
         icon=os.path.join(icons_dir, "ops.mesh.snap_utilities_line"),
         widget="MESH_GGT_snap_point",
         #operator="mesh.snap_utilities_line",
-        keymap="3D View Tool: Edit Mesh, Make Line",
+        keymap=keys.km_tool_snap_utilities_line,
         draw_settings=draw_settings,
     )
 
@@ -81,16 +84,6 @@ def tool_line():
 # -----------------------------------------------------------------------------
 # Tool Registraion
 
-def km_3d_view_snap_tools(tool_mouse = 'LEFTMOUSE'):
-    return [(
-        tool_line.keymap[0],
-        {"space_type": 'VIEW_3D', "region_type": 'WINDOW'},
-        {"items": [
-            ("mesh.snap_utilities_line", {"type": tool_mouse, "value": 'CLICK'},
-             {"properties": [("wait_for_input", False)]}),
-        ]},
-    )]
-
 
 def get_tool_list(space_type, context_mode):
     from bl_ui.space_toolsystem_common import ToolSelectPanelHelper
@@ -102,23 +95,12 @@ def register_snap_tools():
     tools = get_tool_list('VIEW_3D', 'EDIT_MESH')
 
     for index, tool in enumerate(tools, 1):
-        if isinstance(tool, ToolDef) and tool.text == "Measure":
+        if isinstance(tool, ToolDef) and tool.label == "Measure":
             break
 
     tools[:index] += None, tool_line
 
-    del tools, index
-
-    keyconfigs = bpy.context.window_manager.keyconfigs
-    kc_defaultconf = keyconfigs.get("blender")
-    kc_addonconf   = keyconfigs.get("blender addon")
-
-    keyconfig_data = km_3d_view_snap_tools()
-
-    # TODO: find the user defined tool_mouse.
-    from bl_keymap_utils.io import keyconfig_init_from_data
-    keyconfig_init_from_data(kc_defaultconf, keyconfig_data)
-    keyconfig_init_from_data(kc_addonconf, keyconfig_data)
+    del tools
 
 
 def unregister_snap_tools():
@@ -128,16 +110,35 @@ def unregister_snap_tools():
     tools.pop(index)
     tools.remove(tool_line)
 
-    del tools, index
+    del tools
+    del index
+
+
+def register_keymaps():
+    keyconfigs = bpy.context.window_manager.keyconfigs
+    kc_defaultconf = keyconfigs.default
+    kc_addonconf   = keyconfigs.addon
+
+    # TODO: find the user defined tool_mouse.
+    from bl_keymap_utils.io import keyconfig_init_from_data
+    keyconfig_init_from_data(kc_defaultconf, keys.generate_empty_snap_utilities_tools_keymaps())
+    keyconfig_init_from_data(kc_addonconf, keys.generate_snap_utilities_keymaps())
+
+    #snap_modalkeymap = kc_addonconf.keymaps.find(keys.km_snap_utilities_modal_keymap)
+    #snap_modalkeymap.assign("MESH_OT_snap_utilities_line")
 
+
+def unregister_keymaps():
     keyconfigs = bpy.context.window_manager.keyconfigs
     defaultmap = keyconfigs.get("blender").keymaps
     addonmap   = keyconfigs.get("blender addon").keymaps
 
-    for keyconfig_data in km_3d_view_snap_tools():
+    for keyconfig_data in keys.generate_snap_utilities_keymaps():
         km_name, km_args, km_content = keyconfig_data
-
         addonmap.remove(addonmap.find(km_name, **km_args))
+
+    for keyconfig_data in keys.generate_empty_snap_utilities_tools_keymaps():
+        km_name, km_args, km_content = keyconfig_data
         defaultmap.remove(defaultmap.find(km_name, **km_args))
 
 
@@ -158,9 +159,11 @@ def register():
         bpy.utils.register_class(cls)
 
     register_snap_tools()
+    register_keymaps()
 
 
 def unregister():
+    unregister_keymaps()
     unregister_snap_tools()
 
     for cls in reversed(classes):
diff --git a/mesh_snap_utilities_line/common_classes.py b/mesh_snap_utilities_line/common_classes.py
index c36216e08f5616b70a4167070e0fb33d0adddaef..8b4333828bdd8ebd129f3d6c70d8085d05f56471 100644
--- a/mesh_snap_utilities_line/common_classes.py
+++ b/mesh_snap_utilities_line/common_classes.py
@@ -26,6 +26,17 @@ from .common_utilities import (
 
 
 class SnapNavigation():
+    __slots__ = (
+        'use_ndof',
+        '_rotate',
+        '_move',
+        '_zoom',
+        '_ndof_all',
+        '_ndof_orbit',
+        '_ndof_orbit_zoom',
+        '_ndof_pan')
+
+
     @staticmethod
     def debug_key(key):
         for member in dir(key):
@@ -93,10 +104,13 @@ class SnapNavigation():
 
         for key in self._zoom:
             if evkey == key[0:3]:
-                if snap_location and key[3]:
-                    bpy.ops.view3d.zoom_custom_target('INVOKE_DEFAULT', delta=key[3], target=snap_location)
+                if key[3]:
+                    if snap_location:
+                        bpy.ops.view3d.zoom_custom_target('INVOKE_DEFAULT', delta=key[3], target=snap_location)
+                    else:
+                        bpy.ops.view3d.zoom('INVOKE_DEFAULT', delta=key[3])
                 else:
-                    bpy.ops.view3d.zoom('INVOKE_DEFAULT', delta=key[3])
+                    bpy.ops.view3d.zoom('INVOKE_DEFAULT')
                 return True
 
         if self.use_ndof:
@@ -118,6 +132,13 @@ class SnapNavigation():
 
 
 class CharMap:
+    __slots__ = (
+        'unit_system',
+        'uinfo',
+        'length_entered',
+        'length_entered_value',
+        'line_pos')
+
     ascii = {
         ".", ",", "-", "+", "1", "2", "3",
         "4", "5", "6", "7", "8", "9", "0",
@@ -194,16 +215,26 @@ class CharMap:
 
 
 class SnapUtilities:
-#    __slots__ = (
-#        "sctx",
-#        "draw_cache",
-#        "outer_verts",
-#        "snap_face",
-#        "snap_to_grid",
-#        "unit_system",
-#        "rd",
-#        "incremental",
-#    )
+    """
+    __slots__ = (
+        "sctx",
+        "draw_cache",
+        "outer_verts",
+        "unit_system",
+        "rd",
+        "obj",
+        "bm",
+        "geom",
+        "type",
+        "location",
+        "preferences",
+        "normal",
+        "snap_vert",
+        "snap_edge",
+        "snap_face",
+        "incremental",
+    )
+    """
 
     constrain_keys = {
         'X': Vector((1,0,0)),
@@ -327,7 +358,6 @@ class SnapUtilities:
         else:
             #init these variables to avoid errors
             self.obj = context.active_object
-            self.bm = None
             self.geom = None
             self.type = 'OUT'
             self.location = Vector()
diff --git a/mesh_snap_utilities_line/common_utilities.py b/mesh_snap_utilities_line/common_utilities.py
index a6ecbdc98dd6c5af1f1608fccf6c23d77201799a..c62968d59a95d7e3143f23cb0752d0d1d7a0ccf4 100644
--- a/mesh_snap_utilities_line/common_utilities.py
+++ b/mesh_snap_utilities_line/common_utilities.py
@@ -148,16 +148,35 @@ def get_snap_bm_geom(sctx, main_snap_obj, mcursor):
     return r_snp_obj, r_loc, r_elem, r_elem_co, r_view_vector, r_orig, r_bm, r_bm_geom
 
 
-class SnapCache:
-    snp_obj = None
-    edge = None
+class SnapCache(object):
+    __slots__ = 'edge', 'face'
 
-    vmid = None
-    vperp = None
-    v2dmid = None
-    v2dperp = None
+    class Edge:
+        __slots__ = 'snp_obj', 'elem', 'vmid', 'vperp', 'v2dmid', 'v2dperp', 'is_increment'
 
-    is_increment = False
+        def __init__(self):
+            self.snp_obj = None
+            self.elem = None
+            self.vmid = None
+            self.vperp = None
+            self.v2dmid = None
+            self.v2dperp = None
+            self.is_increment = False
+
+    class Face:
+        __slots__ = 'bm_face', 'vmid', 'v2dmid'
+
+        def __init__(self):
+            self.bm_face = None
+
+    def __init__(self):
+        self.edge = self.Edge()
+        self.face = self.Face()
+
+    def clear(self):
+        self.edge.snp_obj = self.face.bm_face = None
+
+_snap_cache = SnapCache()
 
 
 def snap_utilities(
@@ -171,7 +190,7 @@ def snap_utilities(
 
     is_increment = False
     r_loc = None
-    r_type = None
+    r_type = 'OUT'
     r_len = 0.0
 
     if not snp_obj:
@@ -183,71 +202,89 @@ def snap_utilities(
                 t_loc = constrain
             r_loc = t_loc[0]
         else:
-            r_type = 'OUT'
             r_loc = out_Location(sctx.rv3d, orig, view_vector)
 
     elif len(elem) == 1:
         r_type = 'VERT'
+
         if constrain:
             r_loc = intersect_point_line(loc, constrain[0], constrain[1])[0]
         else:
             r_loc = loc
 
     elif len(elem) == 2:
-        if SnapCache.snp_obj is not snp_obj or not (elem == SnapCache.edge).all():
-            SnapCache.snp_obj = snp_obj
-            SnapCache.edge = elem
+        r_type = 'EDGE'
+
+        if _snap_cache.edge.snp_obj is not snp_obj or not (elem == _snap_cache.edge.elem).all():
+            _snap_cache.edge.snp_obj = snp_obj
+            _snap_cache.edge.elem = elem
 
             v0 = elem_co[0]
             v1 = elem_co[1]
-            SnapCache.vmid = 0.5 * (v0 + v1)
-            SnapCache.v2dmid = location_3d_to_region_2d(sctx.region, sctx.rv3d, SnapCache.vmid)
+            _snap_cache.edge.vmid = 0.5 * (v0 + v1)
+            _snap_cache.edge.v2dmid = location_3d_to_region_2d(
+                    sctx.region, sctx.rv3d, _snap_cache.edge.vmid)
 
             if previous_vert and (not bm_geom or previous_vert not in bm_geom.verts):
                 pvert_co = main_snap_obj.mat @ previous_vert.co
                 perp_point = intersect_point_line(pvert_co, v0, v1)
-                SnapCache.vperp = perp_point[0]
+                _snap_cache.edge.vperp = perp_point[0]
                 #factor = point_perpendicular[1]
-                SnapCache.v2dperp = location_3d_to_region_2d(sctx.region, sctx.rv3d, perp_point[0])
-                SnapCache.is_increment = False
+                _snap_cache.edge.v2dperp = location_3d_to_region_2d(sctx.region, sctx.rv3d, perp_point[0])
+                _snap_cache.edge.is_increment = False
             else:
-                SnapCache.is_increment = True
+                _snap_cache.edge.is_increment = True
 
-            #else: SnapCache.v2dperp = None
+            #else: _snap_cache.edge.v2dperp = None
 
         if constrain:
             t_loc = intersect_line_line(constrain[0], constrain[1], elem_co[0], elem_co[1])
-
             if t_loc is None:
                 is_increment = True
                 end = orig + view_vector
                 t_loc = intersect_line_line(constrain[0], constrain[1], orig, end)
             r_loc = t_loc[0]
 
-        elif SnapCache.v2dperp and\
-            abs(SnapCache.v2dperp[0] - mcursor[0]) < 10 and abs(SnapCache.v2dperp[1] - mcursor[1]) < 10:
+        elif _snap_cache.edge.v2dperp and\
+            abs(_snap_cache.edge.v2dperp[0] - mcursor[0]) < 10 and abs(_snap_cache.edge.v2dperp[1] - mcursor[1]) < 10:
                 r_type = 'PERPENDICULAR'
-                r_loc = SnapCache.vperp
+                r_loc = _snap_cache.edge.vperp
 
-        elif abs(SnapCache.v2dmid[0] - mcursor[0]) < 10 and abs(SnapCache.v2dmid[1] - mcursor[1]) < 10:
-            r_type = 'CENTER'
-            r_loc = SnapCache.vmid
+        elif abs(_snap_cache.edge.v2dmid[0] - mcursor[0]) < 10 and abs(_snap_cache.edge.v2dmid[1] - mcursor[1]) < 10:
+                r_type = 'CENTER'
+                r_loc = _snap_cache.edge.vmid
 
         else:
-            is_increment = SnapCache.is_increment
-
-            r_type = 'EDGE'
-            r_loc = loc
+                r_loc = loc
+                is_increment = _snap_cache.edge.is_increment
 
     elif len(elem) == 3:
         r_type = 'FACE'
 
+#        vmid = v2dmid = None
+#        if bm_geom and _snap_cache.face is not bm_geom:
+#            _snap_cache.face.bm_face = bm_geom
+#            vmid = _snap_cache.face.vmid = bm_geom.calc_center_median()
+#            v2dmid = _snap_cache.face.v2dmid = location_3d_to_region_2d(
+#                    sctx.region, sctx.rv3d, _snap_cache.face.vmid)
+
         if constrain:
             is_increment = False
+#            elem_world_co = [snp_obj.mat @ co for co in elem_co]
+#            ray_dir = constrain[1] - constrain[0]
+#            r_loc = intersect_ray_tri(*elem_world_co, ray_dir, constrain[0], False)
+#            if r_loc is None:
+#                r_loc = intersect_ray_tri(*elem_world_co, -ray_dir, constrain[0], False)
+#            if r_loc is None:
             r_loc = intersect_point_line(loc, constrain[0], constrain[1])[0]
+
+#        elif v2dmid and abs(v2dmid[0] - mcursor[0]) < 10 and abs(v2dmid[1] - mcursor[1]) < 10:
+#            r_type = 'CENTER'
+#            r_loc = vmid
+
         else:
-            is_increment = True
             r_loc = loc
+            is_increment = True
 
     if previous_vert:
         pv_co = main_snap_obj.mat @ previous_vert.co
@@ -260,4 +297,4 @@ def snap_utilities(
 
     return snp_obj, loc, r_loc, r_type, bm, bm_geom, r_len
 
-snap_utilities.edge_cache = SnapCache
+snap_utilities.cache = _snap_cache
diff --git a/mesh_snap_utilities_line/drawing_utilities.py b/mesh_snap_utilities_line/drawing_utilities.py
index 92faceccb9f696bd8d77de5f2606127334acb326..0ce679c6ad0102ba4c6af9565ceb20569057e269 100644
--- a/mesh_snap_utilities_line/drawing_utilities.py
+++ b/mesh_snap_utilities_line/drawing_utilities.py
@@ -20,6 +20,24 @@ from mathutils import Vector
 
 
 class SnapDrawn():
+    __slots__ = (
+        'out_color',
+        'face_color',
+        'edge_color',
+        'vert_color',
+        'center_color',
+        'perpendicular_color',
+        'constrain_shift_color',
+        'axis_x_color',
+        'axis_y_color',
+        'axis_z_color',
+        '_format_pos',
+        '_format_pos_and_color',
+        '_program_unif_col',
+        '_program_smooth_col',
+        '_batch_point',
+    )
+
     def __init__(self, out_color, face_color,
                  edge_color, vert_color, center_color,
                  perpendicular_color, constrain_shift_color,
diff --git a/mesh_snap_utilities_line/keys.py b/mesh_snap_utilities_line/keys.py
new file mode 100644
index 0000000000000000000000000000000000000000..29523966e5b82460c8a98b605a52be69e1abd53a
--- /dev/null
+++ b/mesh_snap_utilities_line/keys.py
@@ -0,0 +1,99 @@
+
+#km_snap_utilities_modal_keymap = "Snap Utilities Modal Map"
+
+km_tool_snap_utilities_line = "3D View Tool: Edit Mesh, Make Line"
+
+def km_mesh_snap_utilities_operators():
+    return (
+        "Mesh",
+        {"space_type": 'EMPTY', "region_type": 'WINDOW'},
+        {"items": [
+            ("mesh.snap_utilities_line", {"type": 'K', "value": 'PRESS'},
+             {"properties": [("wait_for_input", True)],
+              "active":False}),
+        ]},
+    )
+
+"""
+def km_snap_utilities_modal_map():
+    items = []
+    modal_enum = []
+    keymap = (
+        km_snap_utilities_modal_keymap,
+        {"space_type": 'EMPTY', "region_type": 'WINDOW', "modal": True, "modal_enum": modal_enum},
+        {"items": items},
+    )
+
+    modal_enum.extend([
+        ("ADD_CUT", "ADD_CUT", ""),
+        ("CANCEL", "CANCEL", ""),
+        ("CONFIRM", "CONFIRM", ""),
+        ("IGNORE_SNAP_ON", "IGNORE_SNAP_ON", ""),
+        ("IGNORE_SNAP_OFF", "IGNORE_SNAP_OFF", ""),
+    ])
+
+    items.extend([
+        ("ADD_CUT", {"type": 'LEFTMOUSE', "value": 'ANY', "any": True}, None),
+        ("CANCEL", {"type": 'ESC', "value": 'PRESS', "any": True}, None),
+        ("CANCEL", {"type": 'LEFTMOUSE', "value": 'DOUBLE_CLICK', "any": True}, None),
+        ("CANCEL", {"type": 'RIGHTMOUSE', "value": 'PRESS', "any": True}, None),
+        ("CONFIRM", {"type": 'RET', "value": 'PRESS', "any": True}, None),
+        ("CONFIRM", {"type": 'NUMPAD_ENTER', "value": 'PRESS', "any": True}, None),
+        ("CONFIRM", {"type": 'SPACE', "value": 'PRESS', "any": True}, None),
+        ("IGNORE_SNAP_ON", {"type": 'LEFT_SHIFT', "value": 'PRESS', "any": True}, None),
+        ("IGNORE_SNAP_OFF", {"type": 'LEFT_SHIFT', "value": 'RELEASE', "any": True}, None),
+        ("IGNORE_SNAP_ON", {"type": 'RIGHT_SHIFT', "value": 'PRESS', "any": True}, None),
+        ("IGNORE_SNAP_OFF", {"type": 'RIGHT_SHIFT', "value": 'RELEASE', "any": True}, None),
+    ])
+
+    return keymap
+"""
+
+def km_3d_view_tool_snap_utilities_line(tool_mouse):
+    return (
+        km_tool_snap_utilities_line,
+        {"space_type": 'VIEW_3D', "region_type": 'WINDOW'},
+        {"items": [
+            ("mesh.snap_utilities_line", {"type": tool_mouse, "value": 'PRESS'},
+             {"properties": [("wait_for_input", False)]}),
+        ]},
+    )
+
+def km_view3d_empty(km_name):
+    return (
+        km_name,
+        {"space_type": 'VIEW_3D', "region_type": 'WINDOW'},
+        {"items": []},
+    )
+
+# ------------------------------------------------------------------------------
+# Full Configuration
+
+def generate_empty_snap_utilities_tools_keymaps():
+    return [
+        #km_view3d_empty(km_snap_utilities_modal_keymap),
+
+        km_view3d_empty(km_tool_snap_utilities_line),
+    ]
+
+def generate_snap_utilities_global_keymaps(tool_mouse = 'LEFTMOUSE'):
+    return [
+        km_mesh_snap_utilities_operators(),
+    ]
+
+def generate_snap_utilities_tools_keymaps(tool_mouse = 'LEFTMOUSE'):
+    return [
+        # Tool System.
+        km_3d_view_tool_snap_utilities_line(tool_mouse),
+    ]
+
+def generate_snap_utilities_keymaps(tool_mouse = 'LEFTMOUSE'):
+    return [
+        km_mesh_snap_utilities_operators(),
+
+        # Modal maps.
+        #km_snap_utilities_modal_map(),
+
+        # Tool System.
+        km_3d_view_tool_snap_utilities_line(tool_mouse),
+    ]
diff --git a/mesh_snap_utilities_line/navigation_ops.py b/mesh_snap_utilities_line/navigation_ops.py
index 21eecc1909c53bcb5d6361c3d91ceda42b9edde3..f08364d8d9140f7b23f422ed96cbd56d2af3d7f3 100644
--- a/mesh_snap_utilities_line/navigation_ops.py
+++ b/mesh_snap_utilities_line/navigation_ops.py
@@ -23,6 +23,8 @@ class VIEW3D_OT_rotate_custom_pivot(bpy.types.Operator):
     bl_label = "Rotate the view"
     bl_options = {'BLOCKING', 'GRAB_CURSOR'}
 
+    __slots__ = 'rv3d', 'init_coord', 'pos1', 'view_rot'
+
     pivot: bpy.props.FloatVectorProperty("Pivot", subtype='XYZ')
     g_up_axis: bpy.props.FloatVectorProperty("up_axis", default=(0.0, 0.0, 1.0), subtype='XYZ')
     sensitivity: bpy.props.FloatProperty("sensitivity", default=0.007)
@@ -64,6 +66,8 @@ class VIEW3D_OT_zoom_custom_target(bpy.types.Operator):
     bl_label = "Zoom the view"
     bl_options = {'BLOCKING', 'GRAB_CURSOR'}
 
+    __slots__ = 'rv3d', 'init_dist', 'delta', 'init_loc'
+
     target: bpy.props.FloatVectorProperty("target", subtype='XYZ')
     delta: bpy.props.IntProperty("delta", default=0)
     step_factor = 0.333
diff --git a/mesh_snap_utilities_line/op_line.py b/mesh_snap_utilities_line/op_line.py
index e25eb9e69de57f96a774d2a588bbe665c9ea64b5..7af0c684050ed176b671e67b011dd87cd93c2100 100644
--- a/mesh_snap_utilities_line/op_line.py
+++ b/mesh_snap_utilities_line/op_line.py
@@ -273,7 +273,7 @@ class SnapUtilitiesLine(SnapUtilities, bpy.types.Operator):
             if self.rv3d.view_matrix != self.rotMat:
                 self.rotMat = self.rv3d.view_matrix.copy()
                 self.bool_update = True
-                snap_utilities.edge_cache.snp_obj = None # hack for snap edge elemens update
+                snap_utilities.cache.clear()
             else:
                 self.bool_update = False
 
@@ -329,13 +329,13 @@ class SnapUtilitiesLine(SnapUtilities, bpy.types.Operator):
                 else:
                     if event.shift:
                         if isinstance(self.geom, bmesh.types.BMEdge):
+                            mat = self.main_snap_obj.mat
+                            verts_co = [mat @ v.co for v in self.geom.verts]
                             if is_making_lines:
                                 loc = self.list_verts_co[-1]
-                                self.vector_constrain = (loc, loc + self.geom.verts[1].co -
-                                                         self.geom.verts[0].co, event.type)
+                                self.vector_constrain = (loc, loc + verts_co[1] - verts_co[0], event.type)
                             else:
-                                self.vector_constrain = [self.main_snap_obj.mat @ v.co for
-                                                         v in self.geom.verts] + [event.type]
+                                self.vector_constrain = verts_co + [event.type]
                     else:
                         if is_making_lines:
                             loc = self.list_verts_co[-1]
@@ -378,7 +378,7 @@ class SnapUtilitiesLine(SnapUtilities, bpy.types.Operator):
                     self._exit(context)
                     return {'FINISHED'}
                 else:
-                    snap_utilities.edge_cache.snp_obj = None # hack for snap edge elemens update
+                    snap_utilities.cache.clear()
                     self.vector_constrain = None
                     self.list_edges = []
                     self.list_verts = []
diff --git a/mesh_snap_utilities_line/preferences.py b/mesh_snap_utilities_line/preferences.py
index 7361284e6afcbc15be3e767726ad44a1232421e1..11b91dc4b85dad3c41cf508d70cf156340d62857 100644
--- a/mesh_snap_utilities_line/preferences.py
+++ b/mesh_snap_utilities_line/preferences.py
@@ -16,6 +16,7 @@
 # ##### END GPL LICENSE BLOCK #####
 
 import bpy
+
 from bpy.props import (
     EnumProperty,
     StringProperty,
@@ -25,6 +26,10 @@ from bpy.props import (
     FloatProperty,
     )
 
+from bpy.app.translations import contexts as i18n_contexts
+
+import rna_keymap_ui
+
 
 class SnapUtilitiesPreferences(bpy.types.AddonPreferences):
     # this must match the addon name, use '__package__'
@@ -67,38 +72,47 @@ class SnapUtilitiesPreferences(bpy.types.AddonPreferences):
             step=1,
             precision=3)
 
-    out_color: FloatVectorProperty(name="OUT", default=(0.0, 0.0, 0.0, 0.5), size=4, subtype="COLOR", min=0, max=1)
-    face_color: FloatVectorProperty(name="FACE", default=(1.0, 0.8, 0.0, 0.5), size=4, subtype="COLOR", min=0, max=1)
-    edge_color: FloatVectorProperty(name="EDGE", default=(0.0, 0.8, 1.0, 0.5), size=4, subtype="COLOR", min=0, max=1)
-    vert_color: FloatVectorProperty(name="VERT", default=(1.0, 0.5, 0.0, 0.5), size=4, subtype="COLOR", min=0, max=1)
-    center_color: FloatVectorProperty(name="CENTER", default=(1.0, 0.0, 1.0, 1.0), size=4, subtype="COLOR", min=0, max=1)
-    perpendicular_color: FloatVectorProperty(name="PERPENDICULAR", default=(0.1, 0.5, 0.5, 1.0), size=4, subtype="COLOR", min=0, max=1)
-    constrain_shift_color: FloatVectorProperty(name="SHIFT CONSTRAIN", default=(0.8, 0.5, 0.4, 1.0), size=4, subtype="COLOR", min=0, max=1)
+    out_color: FloatVectorProperty(name="Floor", default=(0.0, 0.0, 0.0, 0.5), size=4, subtype="COLOR", min=0, max=1)
+    face_color: FloatVectorProperty(name="Face Highlighted", default=(1.0, 0.8, 0.0, 0.5), size=4, subtype="COLOR", min=0, max=1)
+    edge_color: FloatVectorProperty(name="Edge Highlighted", default=(0.0, 0.8, 1.0, 0.5), size=4, subtype="COLOR", min=0, max=1)
+    vert_color: FloatVectorProperty(name="Vertex Highlighted", default=(1.0, 0.5, 0.0, 0.5), size=4, subtype="COLOR", min=0, max=1)
+    center_color: FloatVectorProperty(name="Middle of the Edge", default=(1.0, 0.0, 1.0, 1.0), size=4, subtype="COLOR", min=0, max=1)
+    perpendicular_color: FloatVectorProperty(name="Perpendicular Point", default=(0.1, 0.5, 0.5, 1.0), size=4, subtype="COLOR", min=0, max=1)
+    constrain_shift_color: FloatVectorProperty(name="Shift Constrain", default=(0.8, 0.5, 0.4, 1.0), size=4, subtype="COLOR", min=0, max=1)
+
+    # hidden
+    tabs: EnumProperty(
+        name="Tabs",
+        items = [
+            ("GENERAL", "General", ""),
+            ("KEYMAPS", "Keymaps", ""),
+            ("COLORS", "Colors", ""),
+        ],
+        default="GENERAL")
 
     def draw(self, context):
         layout = self.layout
 
-        layout.label(text="Snap Colors:")
-        split = layout.split()
-
-        col = split.column()
-        col.prop(self, "out_color")
-        col.prop(self, "constrain_shift_color")
-        col = split.column()
-        col.prop(self, "face_color")
-        col = split.column()
-        col.prop(self, "edge_color")
-        col = split.column()
-        col.prop(self, "vert_color")
-        col = split.column()
-        col.prop(self, "center_color")
-        col = split.column()
-        col.prop(self, "perpendicular_color")
-
+        # TAB BAR
         row = layout.row()
+        row.prop(self, "tabs", expand=True)
+
+        box = layout.box()
+
+        if self.tabs == "GENERAL":
+            self.draw_general(box)
 
+        if self.tabs == "COLORS":
+            self.draw_snap_utilities_colors(box)
+
+        elif self.tabs == "KEYMAPS":
+            self.draw_snap_utilities_keymaps(context, box)
+
+    def draw_general(self, layout):
+        row = layout.row()
         col = row.column()
-        #col.label(text="Snap Items:")
+
+        col.label(text="Snap Properties:")
         col.prop(self, "incremental")
         col.prop(self, "increments_grid")
         if self.increments_grid:
@@ -111,3 +125,55 @@ class SnapUtilitiesPreferences(bpy.types.AddonPreferences):
         col.label(text="Line Tool:")
         col.prop(self, "intersect")
         col.prop(self, "create_face")
+
+    def draw_snap_utilities_colors(self, layout):
+        layout.use_property_split = True
+
+        flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False)
+
+        flow.prop(self, "out_color")
+        flow.prop(self, "constrain_shift_color")
+        flow.prop(self, "face_color")
+        flow.prop(self, "edge_color")
+        flow.prop(self, "vert_color")
+        flow.prop(self, "center_color")
+        flow.prop(self, "perpendicular_color")
+
+    def draw_snap_utilities_keymaps(self, context, layout):
+        from .keys import (
+            generate_snap_utilities_global_keymaps,
+            generate_snap_utilities_tools_keymaps,
+        )
+
+        wm = context.window_manager
+        #kc = wm.keyconfigs.addon
+        kc = wm.keyconfigs.user
+
+        layout.label(text="Global:")
+
+        for km_name, km_args, km_content in generate_snap_utilities_global_keymaps():
+            km = kc.keymaps.get(km_name)
+            if km:
+                self.draw_snap_utilities_km(kc, km, layout)
+
+        layout.label(text="Tools:")
+
+        for km_name, km_args, km_content in generate_snap_utilities_tools_keymaps():
+            km = kc.keymaps.get(km_name)
+            if km:
+                self.draw_snap_utilities_km(kc, km, layout)
+
+    @staticmethod
+    def draw_snap_utilities_km(kc, km, layout):
+        layout.context_pointer_set("keymap", km)
+
+        row = layout.row()
+        row.prop(km, "show_expanded_items", text="", emboss=False)
+        row.label(text=km.name, text_ctxt=i18n_contexts.id_windowmanager)
+
+        if km.show_expanded_items:
+            col = layout.column()
+
+            for kmi in km.keymap_items:
+                if "snap_utilities" in kmi.idname:
+                    rna_keymap_ui.draw_kmi(["ADDON", "USER", "DEFAULT"], kc, km, kmi, col, 0)
diff --git a/mesh_snap_utilities_line/snap_context_l/__init__.py b/mesh_snap_utilities_line/snap_context_l/__init__.py
index 32b8bf74bb5bcae5d3f693da089e137f57b0324c..7fa1521595bd2c4715a9311f31581443b2c0cef8 100644
--- a/mesh_snap_utilities_line/snap_context_l/__init__.py
+++ b/mesh_snap_utilities_line/snap_context_l/__init__.py
@@ -198,6 +198,27 @@ class SnapContext():
     :type space: :class:`bpy.types.SpaceView3D`
     """
 
+    __slots__ = (
+        '_dist_px',
+        '_dist_px_sq',
+        '_offscreen',
+        '_offset_cur',
+        '_snap_buffer',
+        '_snap_mode',
+        'depsgraph',
+        'depth_range',
+        'drawn_count',
+        'freed',
+        'last_ray',
+        'mval',
+        'proj_mat',
+        'region',
+        'rv3d',
+        'snap_objects',
+        'threshold',
+        'winsize',
+        )
+
     def __init__(self, depsgraph, region, space):
         #print('Render:', bgl.glGetString(bgl.GL_RENDERER))
         #print('OpenGL Version:', bgl.glGetString(bgl.GL_VERSION))
@@ -208,7 +229,8 @@ class SnapContext():
         self._offset_cur = 1 # Starts with index 1
 
         self.proj_mat = None
-        self.mval = Vector((0, 0))
+        self.mval = Vector((0.0, 0.0))
+        self.last_ray = Vector((1.0, 0.0, 0.0))
         self._snap_mode = VERT | EDGE | FACE
 
         self.set_pixel_dist(12)
diff --git a/mesh_snap_utilities_line/widgets.py b/mesh_snap_utilities_line/widgets.py
index ad0ee2834d11653d9410fd6db1442c118e91de8b..3060d74e0615cd89455105efd89dbab4903afd37 100644
--- a/mesh_snap_utilities_line/widgets.py
+++ b/mesh_snap_utilities_line/widgets.py
@@ -30,7 +30,9 @@ from .drawing_utilities import SnapDrawn
 #    return False
 
 
-class SnapWidgetCommon(SnapUtilities):
+class SnapWidgetCommon(SnapUtilities, bpy.types.Gizmo):
+#    __slots__ = ('inited', 'mode', 'last_mval', 'depsgraph')
+
     snap_to_update = False
 
     def handler(self, scene):
@@ -71,17 +73,18 @@ class SnapWidgetCommon(SnapUtilities):
         SnapUtilities.snapwidgets.append(self)
 
     def end_snapwidget(self):
-        SnapUtilities.snapwidgets.remove(self)
+        if self in SnapUtilities.snapwidgets:
+            SnapUtilities.snapwidgets.remove(self)
 
-        #from .snap_context_l import global_snap_context_get
-        #sctx = global_snap_context_get(None, None, None)
+            #from .snap_context_l import global_snap_context_get
+            #sctx = global_snap_context_get(None, None, None)
 
-        sctx = object.__getattribute__(self, 'sctx')
-        if sctx and not SnapUtilities.snapwidgets:
-            sctx.clear_snap_objects()
+            sctx = object.__getattribute__(self, 'sctx')
+            if sctx and not SnapUtilities.snapwidgets:
+                sctx.clear_snap_objects()
 
-        handler = object.__getattribute__(self, 'handler')
-        bpy.app.handlers.depsgraph_update_post.remove(handler)
+            handler = object.__getattribute__(self, 'handler')
+            bpy.app.handlers.depsgraph_update_post.remove(handler)
 
     def update_snap(self, context, mval):
         if self.last_mval == mval:
@@ -109,7 +112,7 @@ class SnapWidgetCommon(SnapUtilities):
             self.sctx.set_snap_mode(
                      self.snap_vert, self.snap_edge, self.snap_face)
 
-        snap_utilities.edge_cache.snp_obj = None # hack for snap edge elemens update
+        snap_utilities.cache.clear()
         self.snap_obj, prev_loc, self.location, self.type, self.bm, self.geom, len = snap_utilities(
                 self.sctx,
                 None,
@@ -118,9 +121,11 @@ class SnapWidgetCommon(SnapUtilities):
         )
 
 
-class SnapPointWidget(SnapWidgetCommon, bpy.types.Gizmo):
+class SnapPointWidget(SnapWidgetCommon):
     bl_idname = "VIEW3D_GT_snap_point"
 
+    __slots__ = ()
+
     def test_select(self, context, mval):
         if not self.inited:
             self.init_snapwidget(context)
@@ -138,6 +143,7 @@ class SnapPointWidget(SnapWidgetCommon, bpy.types.Gizmo):
     def setup(self):
         self.init_delayed()
 
+
 def context_mode_check(context, widget_group):
     workspace = context.workspace
     mode = workspace.tools_mode
@@ -150,7 +156,7 @@ def context_mode_check(context, widget_group):
     return True
 
 
-class SnapWidgetGroupCommon:
+class SnapWidgetGroupCommon(bpy.types.GizmoGroup):
     bl_space_type = 'VIEW_3D'
     bl_region_type = 'WINDOW'
     bl_options = {'3D'}
@@ -167,7 +173,7 @@ class SnapWidgetGroupCommon:
             object.__getattribute__(self.widget, 'end_snapwidget')()
 
 
-class SnapPointWidgetGroup(SnapWidgetGroupCommon, bpy.types.GizmoGroup):
+class SnapPointWidgetGroup(SnapWidgetGroupCommon):
     bl_idname = "MESH_GGT_snap_point"
     bl_label = "Draw Snap Point"