mirror of
https://github.com/coteditor/CotEditor.git
synced 2024-09-11 19:27:30 +03:00
Import cot as submodule
This commit is contained in:
parent
b3da97f514
commit
94062d4c70
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
[submodule "cot"]
|
||||
path = cot
|
||||
url = git@github.com:coteditor/cot.git
|
@ -583,7 +583,7 @@
|
||||
2A94A45918D08D52009FA90D /* NSWindow+ScriptingSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSWindow+ScriptingSupport.m"; sourceTree = "<group>"; };
|
||||
2A94A45B18D0B562009FA90D /* CEOpacityPanelController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CEOpacityPanelController.h; sourceTree = "<group>"; };
|
||||
2A94A45C18D0B562009FA90D /* CEOpacityPanelController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CEOpacityPanelController.m; sourceTree = "<group>"; };
|
||||
2A94FC781BE2256F00B454A8 /* cot */ = {isa = PBXFileReference; explicitFileType = text.script.python; path = cot; sourceTree = "<group>"; };
|
||||
2A94FC781BE2256F00B454A8 /* cot */ = {isa = PBXFileReference; explicitFileType = text.script.python; name = cot; path = ../cot/cot; sourceTree = SOURCE_ROOT; };
|
||||
2A961C4618FC699E002076B6 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = en; path = en.lproj/Acknowledgements.rtf; sourceTree = "<group>"; };
|
||||
2A961C4818FC699E002076B6 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = en; path = en.lproj/AppleScript.rtf; sourceTree = "<group>"; };
|
||||
2A961C4C18FC699E002076B6 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = en; path = "en.lproj/ScriptMenu Folder.rtf"; sourceTree = "<group>"; };
|
||||
|
243
CotEditor/cot
243
CotEditor/cot
@ -1,243 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
cot
|
||||
|
||||
CotEditor
|
||||
http://coteditor.com
|
||||
|
||||
Created by 1024jp on 2015-08-12.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
© 2015 1024jp
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import argparse
|
||||
import fcntl
|
||||
import os
|
||||
import sys
|
||||
from subprocess import Popen, PIPE
|
||||
|
||||
|
||||
# meta data
|
||||
__version__ = '2.2.0'
|
||||
__description__ = 'command-line utility for CotEditor.'
|
||||
|
||||
|
||||
# constants
|
||||
APPLICATION_NAME = 'CotEditor'
|
||||
|
||||
|
||||
# MARK: Bundle
|
||||
|
||||
def bundle_path():
|
||||
"""Return application path if this script is bundled in an OS X application.
|
||||
|
||||
Returns:
|
||||
path (str): Path to .app directory or None if not found.
|
||||
"""
|
||||
path = os.path.realpath(__file__)
|
||||
|
||||
# find '.app' extension
|
||||
while path is not '/':
|
||||
path = os.path.dirname(path)
|
||||
_, extension = os.path.splitext(path)
|
||||
if extension == '.app':
|
||||
return path
|
||||
|
||||
return None
|
||||
|
||||
|
||||
# MARK: OSA Script
|
||||
|
||||
def run_osascript(script):
|
||||
"""Run osascript.
|
||||
|
||||
Args:
|
||||
script (str): Osascript.
|
||||
Returns:
|
||||
result (str): Return value of the script.
|
||||
"""
|
||||
p = Popen(['osascript', '-'], stdin=PIPE, stdout=PIPE)
|
||||
stdout, _ = p.communicate(script.encode())
|
||||
|
||||
return stdout.decode().rstrip('\n')
|
||||
|
||||
|
||||
class ScriptableApplication(object):
|
||||
"""OSA-Scriptable OS X application object.
|
||||
"""
|
||||
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
|
||||
def tell(self, script):
|
||||
"""Tell OSA command to the application.
|
||||
|
||||
Args:
|
||||
script (str): OSA command
|
||||
Returns:
|
||||
result (str): Return value of the script.
|
||||
"""
|
||||
script = 'tell app "{}" to {}'.format(self.name, script)
|
||||
return run_osascript(script)
|
||||
|
||||
def open(self, path):
|
||||
"""Open given file path in the application.
|
||||
|
||||
Args:
|
||||
path (str): Path to file.
|
||||
"""
|
||||
path = path.replace('"', '\\"')
|
||||
self.tell('open POSIX file "{}"'.format(path))
|
||||
|
||||
def tell_document(self, script, index=1):
|
||||
"""Tell OSA command to a document of the application.
|
||||
|
||||
Args:
|
||||
script (str): OSA command
|
||||
number (int): Index number of the document to handle.
|
||||
Returns:
|
||||
result (str): Return value of the script.
|
||||
"""
|
||||
return self.tell('tell document {} to {}'.format(index, script))
|
||||
|
||||
|
||||
# MARK: Args Parse
|
||||
|
||||
def parse_args():
|
||||
"""Parse command line arguments.
|
||||
|
||||
Returns:
|
||||
Parsed args object.
|
||||
"""
|
||||
# create parser instance
|
||||
parser = argparse.ArgumentParser(description=__description__)
|
||||
|
||||
# set positional argument
|
||||
parser.add_argument('file',
|
||||
type=argparse.FileType('rU'),
|
||||
metavar='FILE',
|
||||
nargs='?',
|
||||
help="Path to file to open."
|
||||
)
|
||||
|
||||
# set optional arguments
|
||||
parser.add_argument('-v', '--version',
|
||||
action='version',
|
||||
version=__version__
|
||||
)
|
||||
parser.add_argument('-g', '--background',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help="Do not bring the application to the foreground."
|
||||
)
|
||||
parser.add_argument('-n', '--new',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help="Create a new blank document."
|
||||
)
|
||||
parser.add_argument('-l', '--line',
|
||||
type=int,
|
||||
help="Jump to specific line in opened document."
|
||||
)
|
||||
parser.add_argument('-c', '--column',
|
||||
type=int,
|
||||
help="Jump to specific column in opened document."
|
||||
)
|
||||
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
# MARK: - Main
|
||||
|
||||
def main(args, stdin):
|
||||
app_identifier = bundle_path() or APPLICATION_NAME
|
||||
app = ScriptableApplication(app_identifier)
|
||||
|
||||
# launch
|
||||
if args.background:
|
||||
app.tell('run')
|
||||
else:
|
||||
app.tell('activate')
|
||||
|
||||
# create document
|
||||
if args.file:
|
||||
# open file
|
||||
path = os.path.abspath(args.file.name)
|
||||
app.open(path)
|
||||
|
||||
elif stdin:
|
||||
# new document with piped text
|
||||
sanitized_stdin = stdin.replace('"', '\\"')
|
||||
app.tell('make new document')
|
||||
app.tell_document('set contents to "{}"'.format(sanitized_stdin))
|
||||
app.tell_document('set range of selection to {0, 0}')
|
||||
|
||||
elif args.new:
|
||||
# new blank document
|
||||
app.tell('make new document')
|
||||
|
||||
if app.tell('number of documents') is '0':
|
||||
return
|
||||
|
||||
# jump to location
|
||||
if args.line is not None or args.column is not None:
|
||||
contents = app.tell_document('contents')
|
||||
lines = contents.splitlines(keepends=True)
|
||||
|
||||
# sanitize line number
|
||||
line = args.line or 1 # line number starts with 1
|
||||
if line == 0:
|
||||
line = 1
|
||||
elif line < 0: # negative line number counts from the last line
|
||||
line_count = len(lines)
|
||||
line = max(1, line_count - abs(line) + 1)
|
||||
|
||||
# count location of line head
|
||||
location = 0
|
||||
for a_line in lines[0:line - 1]:
|
||||
location += len(a_line)
|
||||
|
||||
# sanitize and add column position
|
||||
if args.column is not None:
|
||||
last_line = lines[line - 1]
|
||||
column = min(args.column, len(last_line))
|
||||
location += column
|
||||
|
||||
# set selection range
|
||||
app.tell_document('set range of selection to {{{}, 0}}'.format(
|
||||
location))
|
||||
|
||||
# jump
|
||||
app.tell_document('scroll to caret')
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# parse arguments
|
||||
args = parse_args()
|
||||
|
||||
# read piped text if exists
|
||||
fcntl.fcntl(sys.stdin.fileno(), fcntl.F_SETFL, os.O_NONBLOCK) # non-block
|
||||
try:
|
||||
stdin = sys.stdin.read()
|
||||
except:
|
||||
stdin = None
|
||||
|
||||
main(args, stdin)
|
1
cot
Submodule
1
cot
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit ccb47806829534ca7687a56bd038bcc05b808fba
|
Loading…
Reference in New Issue
Block a user