Skip to content

Instantly share code, notes, and snippets.

@mattst
Last active June 1, 2016 10:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mattst/28a2fbacbe5780c1e0f0434951c102f7 to your computer and use it in GitHub Desktop.
Save mattst/28a2fbacbe5780c1e0f0434951c102f7 to your computer and use it in GitHub Desktop.
import sublime, sublime_plugin
class CopyLine():
"""
A parent class for the CopyLineCommand and CutLineCommand classes.
"""
def copy_line(self, **kwargs):
"""
Copies the cursor line, or all the lines which a multi-line selection
intersects, into the clipboard. It returns the line region that was
copied or None if no copying was performed.
"""
sels = self.view.sel()
# Abort if there is more than one selection.
if len(sels) != 1:
sublime.status_message("Use with only one cursor/selection")
return None
# The optional "inc_trailing_newline" arg defaults to true.
inc_trailing_newline = kwargs.get("inc_trailing_newline", True)
# full_line() and line() both return the region of the whole of all
# the lines that their region parameter intersects, but full_line()
# includes the trailing newline (if there is one).
if inc_trailing_newline:
line_region = self.view.full_line(sels[0])
else:
line_region = self.view.line(sels[0])
# Abort if there is nothing to copy.
if line_region.size() < 1:
return None
copy_str = self.view.substr(line_region)
sublime.set_clipboard(copy_str)
return line_region
class CopyLineCommand(sublime_plugin.TextCommand, CopyLine):
"""
A Sublime Text plugin which copies the cursor line into the clipboard.
"""
def run(self, edit, **kwargs):
line_region = self.copy_line(**kwargs)
if line_region is None:
return
num_chars = line_region.size()
if num_chars == 1: char_word = "character"
else: char_word = "characters"
msg = "Copied %d %s" % (num_chars, char_word)
sublime.status_message(msg)
class CutLineCommand(sublime_plugin.TextCommand, CopyLine):
"""
A Sublime Text plugin which copies the cursor line into the clipboard
and deletes the line.
"""
def run(self, edit, **kwargs):
line_region = self.copy_line(**kwargs)
if line_region is None:
return
self.view.erase(edit, line_region)
num_chars = line_region.size()
if num_chars == 1: char_word = "character"
else: char_word = "characters"
msg = "Cut %d %s" % (num_chars, char_word)
sublime.status_message(msg)
import sublime, sublime_plugin
class CopyLine(sublime_plugin.TextCommand):
"""
A parent class for the CopyLineCommand and CutLineCommand classes.
"""
def copy_line(self, **kwargs):
"""
Copies the cursor line, or all the lines which a multi-line selection
intersects, into the clipboard. It returns the line region that was
copied or None if no copying was performed.
"""
sels = self.view.sel()
# Abort if there is more than one selection.
if len(sels) != 1:
sublime.status_message("Use with only one cursor/selection")
return None
# The optional "inc_trailing_newline" arg defaults to true.
inc_trailing_newline = kwargs.get("inc_trailing_newline", True)
# full_line() and line() both return the region of the whole of all
# the lines that their region parameter intersects, but full_line()
# includes the trailing newline (if there is one).
if inc_trailing_newline:
line_region = self.view.full_line(sels[0])
else:
line_region = self.view.line(sels[0])
# Abort if there is nothing to copy.
if line_region.size() < 1:
return None
copy_str = self.view.substr(line_region)
sublime.set_clipboard(copy_str)
return line_region
class CopyLineCommand(CopyLine):
"""
A Sublime Text plugin which copies the cursor line into the clipboard.
"""
def run(self, edit, **kwargs):
line_region = self.copy_line(**kwargs)
if line_region is None:
return
num_chars = line_region.size()
if num_chars == 1: char_word = "character"
else: char_word = "characters"
msg = "Copied %d %s" % (num_chars, char_word)
sublime.status_message(msg)
class CutLineCommand(CopyLine):
"""
A Sublime Text plugin which copies the cursor line into the clipboard
and deletes the line.
"""
def run(self, edit, **kwargs):
line_region = self.copy_line(**kwargs)
if line_region is None:
return
self.view.erase(edit, line_region)
num_chars = line_region.size()
if num_chars == 1: char_word = "character"
else: char_word = "characters"
msg = "Cut %d %s" % (num_chars, char_word)
sublime.status_message(msg)
import sublime, sublime_plugin
def copy_line(view, **kwargs):
"""
Copies either the cursor line, or all the lines that a multi-line selection
intersects, into the clipboard. It returns the line region which was copied
or None if no copying was performed.
"""
sels = view.sel()
# Abort if there is more than one selection.
if len(sels) != 1:
sublime.status_message("Use with only one cursor/selection")
return None
# The "inc_trailing_newline" arg defaults to true.
inc_trailing_newline = kwargs.get("inc_trailing_newline", True)
if inc_trailing_newline:
# All lines the region intersects plus trailing newline (if any).
line_region = view.full_line(sels[0])
else:
# All lines the region intersects but not a trailing newline.
line_region = view.line(sels[0])
copy_str = view.substr(line_region)
copy_str_len = len(copy_str)
# Abort if there is no text to copy.
if copy_str_len == 0 or (copy_str_len == 1 and copy_str[0] == "\n"):
sublime.status_message("The line is blank")
return None
sublime.set_clipboard(copy_str)
return line_region
def display_message(line_region, cut_line):
"""
Displays the copy or cut status message.
"""
num_chars = line_region.size()
if cut_line: copy_or_cut_word = "Cut"
else: copy_or_cut_word = "Copied"
if num_chars == 1: char_word = "character"
else: char_word = "characters"
msg = "%s %d %s" % (copy_or_cut_word, num_chars, char_word)
sublime.status_message(msg)
class CopyLineCommand(sublime_plugin.TextCommand):
"""
A Sublime Text plugin which copies the cursor line into the clipboard.
"""
def run(self, edit, **kwargs):
line_region = copy_line(self.view, **kwargs)
if line_region is None:
return
cut_line = False
display_message(line_region, cut_line)
class CutLineCommand(sublime_plugin.TextCommand):
"""
A Sublime Text plugin which copies the cursor line into the clipboard
and deletes the line.
"""
def run(self, edit, **kwargs):
line_region = copy_line(self.view, **kwargs)
if line_region is None:
return
self.view.erase(edit, line_region)
cut_line = True
display_message(line_region, cut_line)
@mattst
Copy link
Author

mattst commented May 26, 2016

The 2 code options above are for a StackOverflow question I've made about OO design, both work perfectly well.

EDIT: Implementing r-stein's suggestion in my StackOverflow question led me to option 3 above which is the one to download should anyone want to use the plugin.

In case anyone wants to use this Sublime Text plugin, here's the info.

  • Name: Copy And Cut Line
  • File: CopyAndCutLine.py
  • Requirements: Plugin for Sublime Text v2 and v3
  • ST Commands: copy_line, cut_line
  • Optional Arg: inc_trailing_newline: boolean (default true)

Description:

This plugin for Sublime Text has been designed so that the cursor line can be copied or cut into the clipboard using a single key binding, without the line being selected first. It provides two commands; "copy_line" and "cut_line". When used with a multi-line selection all of the lines that the selection intersects will be copied or cut. However the commands will abort if there is more than one cursor in use - they are designed to be used to quickly copy or cut a line or group of lines without having to select the exact region and are not intended to be used during advanced multiple selection editing when the benefit of using a single key binding to copy or cut a line is negligible. Both commands can take an optional boolean arg called "inc_trailing_newline" which controls whether to include the trailing newline, this defaults to true.

Example keys:

// Include trailing newlines (the default behaviour):
{ "keys": ["ctrl+shift+c"], "command": "copy_line" },
{ "keys": ["ctrl+shift+x"], "command": "cut_line" },

// Do not include trailing newlines:
{ "keys": ["ctrl+shift+c"], "command": "copy_line", "args": {"inc_trailing_newline": false } },
{ "keys": ["ctrl+shift+x"], "command": "cut_line", "args": {"inc_trailing_newline": false } },

Hope this helps.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment