mirror of
https://github.com/wakatime/sublime-wakatime.git
synced 2023-08-10 21:13:02 +03:00
Compare commits
18 Commits
Author | SHA1 | Date | |
---|---|---|---|
b07b59e0c8 | |||
9d715e95b7 | |||
3edaed53aa | |||
865b0bcee9 | |||
d440fe912c | |||
627455167f | |||
aba89d3948 | |||
18d87118e1 | |||
fd91b9e032 | |||
16b15773bf | |||
f0b518862a | |||
7ee7de70d5 | |||
fb479f8e84 | |||
7d37193f65 | |||
6bd62b95db | |||
abf4a94a59 | |||
9337e3173b | |||
57fa4d4d84 |
49
HISTORY.rst
49
HISTORY.rst
@ -3,6 +3,55 @@ History
|
||||
-------
|
||||
|
||||
|
||||
4.0.12 (2015-07-31)
|
||||
++++++++++++++++++
|
||||
|
||||
- correctly use urllib in Python3
|
||||
|
||||
|
||||
4.0.11 (2015-07-31)
|
||||
++++++++++++++++++
|
||||
|
||||
- install python if missing on Windows OS
|
||||
|
||||
|
||||
4.0.10 (2015-07-31)
|
||||
++++++++++++++++++
|
||||
|
||||
- downgrade requests library to v2.6.0
|
||||
|
||||
|
||||
4.0.9 (2015-07-29)
|
||||
++++++++++++++++++
|
||||
|
||||
- catch exceptions from pygments.modeline.get_filetype_from_buffer
|
||||
|
||||
|
||||
4.0.8 (2015-06-23)
|
||||
++++++++++++++++++
|
||||
|
||||
- fix offline logging
|
||||
- limit language detection to known file extensions, unless file contents has a vim modeline
|
||||
- upgrade wakatime cli to v4.0.16
|
||||
|
||||
|
||||
4.0.7 (2015-06-21)
|
||||
++++++++++++++++++
|
||||
|
||||
- allow customizing status bar message in sublime-settings file
|
||||
- guess language using multiple methods, then use most accurate guess
|
||||
- use entity and type for new heartbeats api resource schema
|
||||
- correctly log message from py.warnings module
|
||||
- upgrade wakatime cli to v4.0.15
|
||||
|
||||
|
||||
4.0.6 (2015-05-16)
|
||||
++++++++++++++++++
|
||||
|
||||
- fix bug with auto detecting project name
|
||||
- upgrade wakatime cli to v4.0.13
|
||||
|
||||
|
||||
4.0.5 (2015-05-15)
|
||||
++++++++++++++++++
|
||||
|
||||
|
12
README.md
12
README.md
@ -29,3 +29,15 @@ Screen Shots
|
||||
|
||||

|
||||
|
||||
Troubleshooting
|
||||
---------------
|
||||
|
||||
First, turn on debug mode in your `WakaTime.sublime-settings` file.
|
||||
|
||||

|
||||
|
||||
Add the line: `"debug": true`
|
||||
|
||||
Then, open your Sublime Console with `View -> Show Console` to see the plugin executing the wakatime cli process when sending a heartbeat. Also, tail your `$HOME/.wakatime.log` file to debug wakatime cli problems.
|
||||
|
||||
For more general troubleshooting information, see [wakatime/wakatime#troubleshooting](https://github.com/wakatime/wakatime#troubleshooting).
|
||||
|
33
WakaTime.py
33
WakaTime.py
@ -7,7 +7,7 @@ Website: https://wakatime.com/
|
||||
==========================================================="""
|
||||
|
||||
|
||||
__version__ = '4.0.5'
|
||||
__version__ = '4.0.12'
|
||||
|
||||
|
||||
import sublime
|
||||
@ -19,6 +19,7 @@ import platform
|
||||
import sys
|
||||
import time
|
||||
import threading
|
||||
import urllib
|
||||
import webbrowser
|
||||
from datetime import datetime
|
||||
from subprocess import Popen
|
||||
@ -262,7 +263,7 @@ class SendHeartbeatThread(threading.Thread):
|
||||
|
||||
def set_status_bar(self):
|
||||
if SETTINGS.get('status_bar_message'):
|
||||
self.view.set_status('wakatime', 'WakaTime active {0}'.format(datetime.now().strftime('%I:%M %p')))
|
||||
self.view.set_status('wakatime', datetime.now().strftime(SETTINGS.get('status_bar_message_fmt')))
|
||||
|
||||
def set_last_heartbeat(self):
|
||||
global LAST_HEARTBEAT
|
||||
@ -278,8 +279,12 @@ def plugin_loaded():
|
||||
print('[WakaTime] Initializing WakaTime plugin v%s' % __version__)
|
||||
|
||||
if not python_binary():
|
||||
sublime.error_message("Unable to find Python binary!\nWakaTime needs Python to work correctly.\n\nGo to https://www.python.org/downloads")
|
||||
return
|
||||
print('[WakaTime] Warning: Python binary not found.')
|
||||
if platform.system() == 'Windows':
|
||||
install_python()
|
||||
else:
|
||||
sublime.error_message("Unable to find Python binary!\nWakaTime needs Python to work correctly.\n\nGo to https://www.python.org/downloads")
|
||||
return
|
||||
|
||||
SETTINGS = sublime.load_settings(SETTINGS_FILE)
|
||||
after_loaded()
|
||||
@ -290,6 +295,26 @@ def after_loaded():
|
||||
sublime.set_timeout(after_loaded, 500)
|
||||
|
||||
|
||||
def install_python():
|
||||
print('[WakaTime] Downloading and installing python...')
|
||||
url = 'https://www.python.org/ftp/python/3.4.3/python-3.4.3.msi'
|
||||
if platform.architecture()[0] == '64bit':
|
||||
url = 'https://www.python.org/ftp/python/3.4.3/python-3.4.3.amd64.msi'
|
||||
python_msi = os.path.join(os.path.expanduser('~'), 'python.msi')
|
||||
try:
|
||||
urllib.urlretrieve(url, python_msi)
|
||||
except AttributeError:
|
||||
urllib.request.urlretrieve(url, python_msi)
|
||||
args = [
|
||||
'msiexec',
|
||||
'/i',
|
||||
python_msi,
|
||||
'/norestart',
|
||||
'/qb!',
|
||||
]
|
||||
Popen(args)
|
||||
|
||||
|
||||
# need to call plugin_loaded because only ST3 will auto-call it
|
||||
if ST_VERSION < 3000:
|
||||
plugin_loaded()
|
||||
|
@ -16,5 +16,8 @@
|
||||
|
||||
// Status bar message. Set to false to hide status bar message.
|
||||
// Defaults to true.
|
||||
"status_bar_message": true
|
||||
"status_bar_message": true,
|
||||
|
||||
// Status bar message format.
|
||||
"status_bar_message_fmt": "WakaTime active %I:%M %p"
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
__title__ = 'wakatime'
|
||||
__description__ = 'Common interface to the WakaTime api.'
|
||||
__url__ = 'https://github.com/wakatime/wakatime'
|
||||
__version_info__ = ('4', '0', '12')
|
||||
__version_info__ = ('4', '1', '0')
|
||||
__version__ = '.'.join(__version_info__)
|
||||
__author__ = 'Alan Hamlett'
|
||||
__author_email__ = 'alan@wakatime.com'
|
||||
|
@ -19,6 +19,7 @@ import re
|
||||
import sys
|
||||
import time
|
||||
import traceback
|
||||
import socket
|
||||
try:
|
||||
import ConfigParser as configparser
|
||||
except ImportError:
|
||||
@ -34,7 +35,7 @@ from .offlinequeue import Queue
|
||||
from .packages import argparse
|
||||
from .packages import simplejson as json
|
||||
from .packages.requests.exceptions import RequestException
|
||||
from .project import find_project
|
||||
from .project import get_project_info
|
||||
from .session_cache import SessionCache
|
||||
from .stats import get_file_stats
|
||||
try:
|
||||
@ -161,6 +162,7 @@ def parseArguments(argv):
|
||||
help='optional project name')
|
||||
parser.add_argument('--alternate-project', dest='alternate_project',
|
||||
help='optional alternate project name; auto-discovered project takes priority')
|
||||
parser.add_argument('--hostname', dest='hostname', help='hostname of current machine.')
|
||||
parser.add_argument('--disableoffline', dest='offline',
|
||||
action='store_false',
|
||||
help='disables offline time logging instead of queuing logged time')
|
||||
@ -303,7 +305,7 @@ def get_user_agent(plugin):
|
||||
return user_agent
|
||||
|
||||
|
||||
def send_heartbeat(project=None, branch=None, stats={}, key=None, targetFile=None,
|
||||
def send_heartbeat(project=None, branch=None, hostname=None, stats={}, key=None, targetFile=None,
|
||||
timestamp=None, isWrite=None, plugin=None, offline=None, notfile=False,
|
||||
hidefilenames=None, proxy=None, api_url=None, **kwargs):
|
||||
"""Sends heartbeat as POST request to WakaTime api server.
|
||||
@ -314,14 +316,15 @@ def send_heartbeat(project=None, branch=None, stats={}, key=None, targetFile=Non
|
||||
log.debug('Sending heartbeat to api at %s' % api_url)
|
||||
data = {
|
||||
'time': timestamp,
|
||||
'file': targetFile,
|
||||
'entity': targetFile,
|
||||
'type': 'file',
|
||||
}
|
||||
if hidefilenames and targetFile is not None and not notfile:
|
||||
data['file'] = data['file'].rsplit('/', 1)[-1].rsplit('\\', 1)[-1]
|
||||
if len(data['file'].strip('.').split('.', 1)) > 1:
|
||||
data['file'] = u('HIDDEN.{ext}').format(ext=u(data['file'].strip('.').rsplit('.', 1)[-1]))
|
||||
data['entity'] = data['entity'].rsplit('/', 1)[-1].rsplit('\\', 1)[-1]
|
||||
if len(data['entity'].strip('.').split('.', 1)) > 1:
|
||||
data['entity'] = u('HIDDEN.{ext}').format(ext=u(data['entity'].strip('.').rsplit('.', 1)[-1]))
|
||||
else:
|
||||
data['file'] = u('HIDDEN')
|
||||
data['entity'] = u('HIDDEN')
|
||||
if stats.get('lines'):
|
||||
data['lines'] = stats['lines']
|
||||
if stats.get('language'):
|
||||
@ -350,6 +353,8 @@ def send_heartbeat(project=None, branch=None, stats={}, key=None, targetFile=Non
|
||||
'Accept': 'application/json',
|
||||
'Authorization': auth,
|
||||
}
|
||||
if hostname:
|
||||
headers['X-Machine-Name'] = hostname
|
||||
proxies = {}
|
||||
if proxy:
|
||||
proxies['https'] = proxy
|
||||
@ -442,24 +447,17 @@ def main(argv=None):
|
||||
stats = get_file_stats(args.targetFile, notfile=args.notfile,
|
||||
lineno=args.lineno, cursorpos=args.cursorpos)
|
||||
|
||||
project = None
|
||||
project, branch = None, None
|
||||
if not args.notfile:
|
||||
project = find_project(args.targetFile, configs=configs)
|
||||
branch = None
|
||||
project_name = args.project
|
||||
if project:
|
||||
branch = project.branch()
|
||||
if not project_name:
|
||||
project_name = project.name()
|
||||
if not project_name:
|
||||
project_name = args.alternate_project
|
||||
project, branch = get_project_info(configs=configs, args=args)
|
||||
|
||||
if send_heartbeat(
|
||||
project=project_name,
|
||||
branch=branch,
|
||||
stats=stats,
|
||||
**vars(args)
|
||||
):
|
||||
kwargs = vars(args)
|
||||
kwargs['project'] = project
|
||||
kwargs['branch'] = branch
|
||||
kwargs['stats'] = stats
|
||||
kwargs['hostname'] = args.hostname or socket.gethostname()
|
||||
|
||||
if send_heartbeat(**kwargs):
|
||||
queue = Queue()
|
||||
while True:
|
||||
heartbeat = queue.pop()
|
||||
@ -470,6 +468,7 @@ def main(argv=None):
|
||||
targetFile=heartbeat['file'],
|
||||
timestamp=heartbeat['time'],
|
||||
branch=heartbeat['branch'],
|
||||
hostname=kwargs['hostname'],
|
||||
stats=json.loads(heartbeat['stats']),
|
||||
key=args.key,
|
||||
isWrite=heartbeat['is_write'],
|
||||
|
@ -11,8 +11,25 @@
|
||||
|
||||
import os
|
||||
import sys
|
||||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
import wakatime
|
||||
|
||||
|
||||
# get path to local wakatime package
|
||||
package_folder = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
# add local wakatime package to sys.path
|
||||
sys.path.insert(0, package_folder)
|
||||
|
||||
# import local wakatime package
|
||||
try:
|
||||
import wakatime
|
||||
except TypeError:
|
||||
# on Windows, non-ASCII characters in import path can be fixed using
|
||||
# the script path from sys.argv[0].
|
||||
# More info at https://github.com/wakatime/wakatime/issues/32
|
||||
package_folder = os.path.dirname(os.path.dirname(os.path.abspath(sys.argv[0])))
|
||||
sys.path.insert(0, package_folder)
|
||||
import wakatime
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(wakatime.main(sys.argv))
|
||||
|
@ -37,15 +37,17 @@ class CustomEncoder(json.JSONEncoder):
|
||||
|
||||
class JsonFormatter(logging.Formatter):
|
||||
|
||||
def setup(self, timestamp, isWrite, targetFile, version, plugin, verbose):
|
||||
def setup(self, timestamp, isWrite, targetFile, version, plugin, verbose,
|
||||
warnings=False):
|
||||
self.timestamp = timestamp
|
||||
self.isWrite = isWrite
|
||||
self.targetFile = targetFile
|
||||
self.version = version
|
||||
self.plugin = plugin
|
||||
self.verbose = verbose
|
||||
self.warnings = warnings
|
||||
|
||||
def format(self, record):
|
||||
def format(self, record, *args):
|
||||
data = OrderedDict([
|
||||
('now', self.formatTime(record, self.datefmt)),
|
||||
])
|
||||
@ -60,7 +62,7 @@ class JsonFormatter(logging.Formatter):
|
||||
if not self.isWrite:
|
||||
del data['isWrite']
|
||||
data['level'] = record.levelname
|
||||
data['message'] = record.msg
|
||||
data['message'] = record.getMessage() if self.warnings else record.msg
|
||||
if not self.plugin:
|
||||
del data['plugin']
|
||||
return CustomEncoder().encode(data)
|
||||
@ -77,7 +79,6 @@ def set_log_level(logger, args):
|
||||
|
||||
|
||||
def setup_logging(args, version):
|
||||
logging.captureWarnings(True)
|
||||
logger = logging.getLogger('WakaTime')
|
||||
set_log_level(logger, args)
|
||||
if len(logger.handlers) > 0:
|
||||
@ -107,5 +108,23 @@ def setup_logging(args, version):
|
||||
)
|
||||
handler.setFormatter(formatter)
|
||||
logger.addHandler(handler)
|
||||
logging.getLogger('py.warnings').addHandler(handler)
|
||||
|
||||
warnings_formatter = JsonFormatter(datefmt='%Y/%m/%d %H:%M:%S %z')
|
||||
warnings_formatter.setup(
|
||||
timestamp=args.timestamp,
|
||||
isWrite=args.isWrite,
|
||||
targetFile=args.targetFile,
|
||||
version=version,
|
||||
plugin=args.plugin,
|
||||
verbose=args.verbose,
|
||||
warnings=True,
|
||||
)
|
||||
warnings_handler = logging.FileHandler(os.path.expanduser(logfile))
|
||||
warnings_handler.setFormatter(warnings_formatter)
|
||||
logging.getLogger('py.warnings').addHandler(warnings_handler)
|
||||
try:
|
||||
logging.captureWarnings(True)
|
||||
except AttributeError:
|
||||
pass # Python >= 2.7 is needed to capture warnings
|
||||
|
||||
return logger
|
||||
|
@ -50,7 +50,7 @@ class Queue(object):
|
||||
try:
|
||||
conn, c = self.connect()
|
||||
heartbeat = {
|
||||
'file': data.get('file'),
|
||||
'file': data.get('entity'),
|
||||
'time': data.get('time'),
|
||||
'project': data.get('project'),
|
||||
'branch': data.get('branch'),
|
||||
|
@ -15,30 +15,70 @@ from .projects.git import Git
|
||||
from .projects.mercurial import Mercurial
|
||||
from .projects.projectmap import ProjectMap
|
||||
from .projects.subversion import Subversion
|
||||
from .projects.wakatime import WakaTime
|
||||
from .projects.wakatime_project_file import WakaTimeProjectFile
|
||||
|
||||
|
||||
log = logging.getLogger('WakaTime')
|
||||
|
||||
|
||||
# List of plugin classes to find a project for the current file path.
|
||||
# Project plugins will be processed with priority in the order below.
|
||||
PLUGINS = [
|
||||
WakaTime,
|
||||
CONFIG_PLUGINS = [
|
||||
WakaTimeProjectFile,
|
||||
ProjectMap,
|
||||
]
|
||||
REV_CONTROL_PLUGINS = [
|
||||
Git,
|
||||
Mercurial,
|
||||
Subversion,
|
||||
]
|
||||
|
||||
|
||||
def find_project(path, configs=None):
|
||||
for plugin in PLUGINS:
|
||||
plugin_name = plugin.__name__.lower()
|
||||
plugin_configs = None
|
||||
if configs and configs.has_section(plugin_name):
|
||||
plugin_configs = dict(configs.items(plugin_name))
|
||||
project = plugin(path, configs=plugin_configs)
|
||||
def get_project_info(configs=None, args=None):
|
||||
"""Find the current project and branch.
|
||||
|
||||
First looks for a .wakatime-project file. Second, uses the --project arg.
|
||||
Third, uses the folder name from a revision control repository. Last, uses
|
||||
the --alternate-project arg.
|
||||
|
||||
Returns a project, branch tuple.
|
||||
"""
|
||||
|
||||
project_name, branch_name = None, None
|
||||
|
||||
for plugin_cls in CONFIG_PLUGINS:
|
||||
|
||||
plugin_name = plugin_cls.__name__.lower()
|
||||
plugin_configs = get_configs_for_plugin(plugin_name, configs)
|
||||
|
||||
project = plugin_cls(args.targetFile, configs=plugin_configs)
|
||||
if project.process():
|
||||
return project
|
||||
project_name = project.name()
|
||||
branch_name = project.branch()
|
||||
break
|
||||
|
||||
if project_name is None:
|
||||
project_name = args.project
|
||||
|
||||
if project_name is None or branch_name is None:
|
||||
|
||||
for plugin_cls in REV_CONTROL_PLUGINS:
|
||||
|
||||
plugin_name = plugin_cls.__name__.lower()
|
||||
plugin_configs = get_configs_for_plugin(plugin_name, configs)
|
||||
|
||||
project = plugin_cls(args.targetFile, configs=plugin_configs)
|
||||
if project.process():
|
||||
project_name = project_name or project.name()
|
||||
branch_name = branch_name or project.branch()
|
||||
break
|
||||
|
||||
if project_name is None:
|
||||
project_name = args.alternate_project
|
||||
|
||||
return project_name, branch_name
|
||||
|
||||
|
||||
def get_configs_for_plugin(plugin_name, configs):
|
||||
if configs and configs.has_section(plugin_name):
|
||||
return dict(configs.items(plugin_name))
|
||||
return None
|
||||
|
@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
wakatime.projects.wakatime
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
wakatime.projects.wakatime_project_file
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Information from a .wakatime-project file about the project for
|
||||
a given file. First line of .wakatime-project sets the project
|
||||
@ -21,7 +21,7 @@ from ..compat import u, open
|
||||
log = logging.getLogger('WakaTime')
|
||||
|
||||
|
||||
class WakaTime(BaseProject):
|
||||
class WakaTimeProjectFile(BaseProject):
|
||||
|
||||
def process(self):
|
||||
self.config = self._find_config(self.path)
|
@ -20,13 +20,15 @@ if sys.version_info[0] == 2:
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), 'packages', 'pygments_py2'))
|
||||
else:
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), 'packages', 'pygments_py3'))
|
||||
from pygments.lexers import guess_lexer_for_filename
|
||||
from pygments.lexers import get_lexer_by_name, guess_lexer_for_filename
|
||||
from pygments.modeline import get_filetype_from_buffer
|
||||
from pygments.util import ClassNotFound
|
||||
|
||||
|
||||
log = logging.getLogger('WakaTime')
|
||||
|
||||
|
||||
# force file name extensions to be recognized as a certain language
|
||||
# extensions taking priority over lexer
|
||||
EXTENSIONS = {
|
||||
'j2': 'HTML',
|
||||
'markdown': 'Markdown',
|
||||
@ -34,6 +36,8 @@ EXTENSIONS = {
|
||||
'mdown': 'Markdown',
|
||||
'twig': 'Twig',
|
||||
}
|
||||
|
||||
# lexers to human readable languages
|
||||
TRANSLATIONS = {
|
||||
'CSS+Genshi Text': 'CSS',
|
||||
'CSS+Lasso': 'CSS',
|
||||
@ -45,31 +49,132 @@ TRANSLATIONS = {
|
||||
'RHTML': 'HTML',
|
||||
}
|
||||
|
||||
# extensions for when no lexer is found
|
||||
AUXILIARY_EXTENSIONS = {
|
||||
'vb': 'VB.net',
|
||||
}
|
||||
|
||||
|
||||
def guess_language(file_name):
|
||||
language, lexer = None, None
|
||||
try:
|
||||
with open(file_name, 'r', encoding='utf-8') as fh:
|
||||
lexer = guess_lexer_for_filename(file_name, fh.read(512000))
|
||||
except:
|
||||
pass
|
||||
"""Guess lexer and language for a file.
|
||||
|
||||
Returns (language, lexer) tuple where language is a unicode string.
|
||||
"""
|
||||
|
||||
lexer = smart_guess_lexer(file_name)
|
||||
|
||||
language = None
|
||||
|
||||
# guess language from file extension
|
||||
if file_name:
|
||||
language = guess_language_from_extension(file_name.rsplit('.', 1)[-1])
|
||||
if lexer and language is None:
|
||||
language = translate_language(u(lexer.name))
|
||||
language = get_language_from_extension(file_name, EXTENSIONS)
|
||||
|
||||
# get language from lexer if we didn't have a hard-coded extension rule
|
||||
if language is None and lexer:
|
||||
language = u(lexer.name)
|
||||
|
||||
if language is None:
|
||||
language = get_language_from_extension(file_name, AUXILIARY_EXTENSIONS)
|
||||
|
||||
if language is not None:
|
||||
language = translate_language(language)
|
||||
|
||||
return language, lexer
|
||||
|
||||
|
||||
def guess_language_from_extension(extension):
|
||||
def smart_guess_lexer(file_name):
|
||||
"""Guess Pygments lexer for a file.
|
||||
|
||||
Looks for a vim modeline in file contents, then compares the accuracy
|
||||
of that lexer with a second guess. The second guess looks up all lexers
|
||||
matching the file name, then runs a text analysis for the best choice.
|
||||
"""
|
||||
lexer = None
|
||||
|
||||
text = get_file_contents(file_name)
|
||||
|
||||
lexer_1, accuracy_1 = guess_lexer_using_filename(file_name, text)
|
||||
lexer_2, accuracy_2 = guess_lexer_using_modeline(text)
|
||||
|
||||
if lexer_1:
|
||||
lexer = lexer_1
|
||||
if (lexer_2 and accuracy_2 and
|
||||
(not accuracy_1 or accuracy_2 > accuracy_1)):
|
||||
lexer = lexer_2
|
||||
|
||||
return lexer
|
||||
|
||||
|
||||
def guess_lexer_using_filename(file_name, text):
|
||||
"""Guess lexer for given text, limited to lexers for this file's extension.
|
||||
|
||||
Returns a tuple of (lexer, accuracy).
|
||||
"""
|
||||
|
||||
lexer, accuracy = None, None
|
||||
|
||||
try:
|
||||
lexer = guess_lexer_for_filename(file_name, text)
|
||||
except:
|
||||
pass
|
||||
|
||||
if lexer is not None:
|
||||
try:
|
||||
accuracy = lexer.analyse_text(text)
|
||||
except:
|
||||
pass
|
||||
|
||||
return lexer, accuracy
|
||||
|
||||
|
||||
def guess_lexer_using_modeline(text):
|
||||
"""Guess lexer for given text using Vim modeline.
|
||||
|
||||
Returns a tuple of (lexer, accuracy).
|
||||
"""
|
||||
|
||||
lexer, accuracy = None, None
|
||||
|
||||
file_type = None
|
||||
try:
|
||||
file_type = get_filetype_from_buffer(text)
|
||||
except:
|
||||
pass
|
||||
|
||||
if file_type is not None:
|
||||
try:
|
||||
lexer = get_lexer_by_name(file_type)
|
||||
except ClassNotFound:
|
||||
pass
|
||||
|
||||
if lexer is not None:
|
||||
try:
|
||||
accuracy = lexer.analyse_text(text)
|
||||
except:
|
||||
pass
|
||||
|
||||
return lexer, accuracy
|
||||
|
||||
|
||||
def get_language_from_extension(file_name, extension_map):
|
||||
"""Returns a matching language for the given file_name using extension_map.
|
||||
"""
|
||||
|
||||
extension = file_name.rsplit('.', 1)[-1] if len(file_name.rsplit('.', 1)) > 1 else None
|
||||
|
||||
if extension:
|
||||
if extension in EXTENSIONS:
|
||||
return EXTENSIONS[extension]
|
||||
if extension.lower() in EXTENSIONS:
|
||||
return EXTENSIONS[extension.lower()]
|
||||
if extension in extension_map:
|
||||
return extension_map[extension]
|
||||
if extension.lower() in extension_map:
|
||||
return extension_map[extension.lower()]
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def translate_language(language):
|
||||
"""Turns Pygments lexer class name string into human-readable language.
|
||||
"""
|
||||
|
||||
if language in TRANSLATIONS:
|
||||
language = TRANSLATIONS[language]
|
||||
return language
|
||||
@ -107,3 +212,16 @@ def get_file_stats(file_name, notfile=False, lineno=None, cursorpos=None):
|
||||
'cursorpos': cursorpos,
|
||||
}
|
||||
return stats
|
||||
|
||||
|
||||
def get_file_contents(file_name):
|
||||
"""Returns the first 512000 bytes of the file's contents.
|
||||
"""
|
||||
|
||||
text = None
|
||||
try:
|
||||
with open(file_name, 'r', encoding='utf-8') as fh:
|
||||
text = fh.read(512000)
|
||||
except:
|
||||
pass
|
||||
return text
|
||||
|
Reference in New Issue
Block a user