IGRACH
IGRACH

Reputation: 3633

Deleting until whitespace in Sublime Text

Is there any way to delete all characters untill first whitespace in Sublime. I know that you can use ctrl+delete to do that but it stops at non-word characters(",:,&,*, etc). When you try to delete aaa aaa 2+a, from the end, it will delete 2+a until + sign, but it will delete aaa until space. I need to change that so it will delete 2+a until first space. Solution can be anything; changing settings, plug-in.

Upvotes: 0

Views: 479

Answers (2)

IGRACH
IGRACH

Reputation: 3633

I found solution for this. It's via this plugin:

https://packagecontrol.io/packages/KeyboardNavigation

Key for it is:

{ "keys": ["ctrl+backspace"], "command": "delete_to_beg_of_contig_boundary", "args": {"forward": false} }

It deletes any characters right to left until first whitespace.

Upvotes: 1

mattst
mattst

Reputation: 14020

I have written a Sublime Text plugin to delete text as you require. It is almost identical to ST's delete_word command but breaks only at whitespace/non-whitespace.

When called the plugin deletes text from the cursor to the next or previous group of characters, the grouping being defined as either whitespace or non-whitespace characters. Thus if run several times in succession it will alternate between deleting groups of whitespace and non-whitespace characters ahead or behind the cursor. The forwards parameter of the run() method (i.e. the command's arg) controls the deletion direction.

Save the plugin somewhere in your config Packages folder hierarchy. e.g.

.../sublime-text-3/Packages/User/DeleteToWhitespace.py

Add key bindings to your user .sublime-keymap file. e.g.

// 
// These key bindings override the ST 'delete_word' keys but use whatever keys you want.
// You could use `super+delete` and `super+backspace` and keep ST's delete keys intact.
// 
{ "keys": ["ctrl+delete"], "command": "delete_to_whitespace", "args": {"forwards": true} },
{ "keys": ["ctrl+backspace"], "command": "delete_to_whitespace", "args": {"forwards": false} },

Below is the DeleteToWhitespace.py plugin. It has been uploaded to this GitHub Gist – this links directly to the raw source code.

#
# Name:        Delete To Whitespace
# Requires:    Plugin for Sublime Text v3
# Command:     delete_to_whitespace
# Args:        forwards: bool (delete backwards if false)
# License:     MIT License
#

import sublime, sublime_plugin, re

class DeleteToWhitespaceCommand(sublime_plugin.TextCommand):
    """
    A Sublime Text plugin that deletes text from the cursor to the next or
    previous group of characters, the grouping being defined as either
    whitespace or non-whitespace characters. Thus if run several times in
    succession it will alternate between deleting groups of whitespace and
    non-whitespace ahead or behind the cursor. The forwards parameter of the
    run() method (i.e. the command's arg) controls the deletion direction.
    """

    def run(self, edit, forwards=True):
        self.edit = edit
        self.forwards = forwards

        if forwards:
            self.delete_forwards()
        else:
            self.delete_backwards()

    def delete_forwards(self):
        whitespace_regex = "^\s+"
        non_whitespace_regex = "^\S+"

        for sel in self.view.sel():

            if sel.size() > 0:
                self.view.erase(self.edit, sel)
                continue

            # ∴ sel.a == sel.b == sel.begin() == sel.end()
            # view.full_line() includes the trailing newline (if any).
            cursor = sel.a
            line = self.view.full_line(cursor)
            cursor_to_eol = sublime.Region(cursor, line.end())
            cursor_to_eol_str = self.view.substr(cursor_to_eol)

            match = re.search(whitespace_regex, cursor_to_eol_str)
            if match:
                self.erase_matching_characters(cursor, match)
                continue

            match = re.search(non_whitespace_regex, cursor_to_eol_str)
            if match:
                self.erase_matching_characters(cursor, match)
                continue

    def delete_backwards(self):
        whitespace_regex = "\s+$"
        non_whitespace_regex = "\S+$"

        for sel in self.view.sel():

            if sel.size() > 0:
                self.view.erase(self.edit, sel)
                continue

            # ∴ sel.a == sel.b == sel.begin() == sel.end()
            # view.line() excludes the trailing newline (if any).
            cursor = sel.a
            line = self.view.line(cursor)
            cursor_to_bol = sublime.Region(cursor, line.begin())
            cursor_to_bol_str = self.view.substr(cursor_to_bol)

            # Delete the newline of the 'previous' line.
            if cursor_to_bol.size() == 0 and cursor > 0:
                erase_region = sublime.Region(cursor, cursor - 1)
                self.view.erase(self.edit, erase_region)
                continue

            match = re.search(whitespace_regex, cursor_to_bol_str)
            if match:
                self.erase_matching_characters(cursor, match)
                continue

            match = re.search(non_whitespace_regex, cursor_to_bol_str)
            if match:
                self.erase_matching_characters(cursor, match)
                continue

    def erase_matching_characters(self, cursor, match):
        match_len = match.end() - match.start()
        if self.forwards:
            erase_region = sublime.Region(cursor, cursor + match_len)
        else:
            erase_region = sublime.Region(cursor, cursor - match_len)
        self.view.erase(self.edit, erase_region)

Upvotes: 0

Related Questions