[acronyms] Complete rewrite of the plugin
This commit is contained in:
@@ -1,69 +0,0 @@
|
|||||||
{"afaik": "as far as I know",
|
|
||||||
"afaict": "as far as I can tell",
|
|
||||||
"afk": "away from keyboard",
|
|
||||||
"atm": "at the moment",
|
|
||||||
"bbiab": "be back in a bit",
|
|
||||||
"bbiaf": "be back in a few (minutes)",
|
|
||||||
"bbl": "be back later",
|
|
||||||
"bbs": "be back soon",
|
|
||||||
"b/c": "because",
|
|
||||||
"bf": "boyfriend",
|
|
||||||
"bfo": "blinding flash of the obvious",
|
|
||||||
"brb": "be right back",
|
|
||||||
"bsod": "blue screen of death",
|
|
||||||
"btw": "by the way",
|
|
||||||
"ciao": "Italian for goodbye",
|
|
||||||
"ctrn": "can't talk right now",
|
|
||||||
"cul8r": "see you later",
|
|
||||||
"cya": "see ya",
|
|
||||||
"dhtb": "don't have the bandwidth",
|
|
||||||
"f2f": "face to face",
|
|
||||||
"fubar": "fucked up beyond all recognition",
|
|
||||||
"fwiw": "for what it's worth",
|
|
||||||
"fyi": "for your information",
|
|
||||||
"gmta": "great minds think alike",
|
|
||||||
"iam": "in a meeting",
|
|
||||||
"ianal": "I am not a lawyer",
|
|
||||||
"ihmb": "I hate my boss",
|
|
||||||
"iirc": "if I recall correctly",
|
|
||||||
"imho": "in my humble opinion",
|
|
||||||
"imo": "in my opinion",
|
|
||||||
"iow": "in other words",
|
|
||||||
"irl": "in real life",
|
|
||||||
"<g>": "grin",
|
|
||||||
"*g*": "grin",
|
|
||||||
"gf": "girlfriend",
|
|
||||||
"gmta": "great minds think alike",
|
|
||||||
"g2g": "got to go",
|
|
||||||
"jid": "jabber identifier",
|
|
||||||
"j/k": "just kidding",
|
|
||||||
"ok": "okay",
|
|
||||||
"lol": "laugh out loud",
|
|
||||||
"l8r": "later",
|
|
||||||
"msg": "message",
|
|
||||||
"n/m": "never mind",
|
|
||||||
"n/p": "no problem",
|
|
||||||
"oAo": "over and out!",
|
|
||||||
"omg": "oh my god",
|
|
||||||
"oob": "out of band",
|
|
||||||
"otoh": "on the other hand",
|
|
||||||
"oww": "oops, wrong window!",
|
|
||||||
"otp": "on the phone",
|
|
||||||
"pita": "pain in the ass",
|
|
||||||
"pov": "point of view",
|
|
||||||
"pw": "password",
|
|
||||||
"rotfl": "rolling on the floor laughing",
|
|
||||||
"rsn": "real soon now",
|
|
||||||
"rtfm": "read the friendly manual",
|
|
||||||
"slap": "sounds like a plan",
|
|
||||||
"thx": "thanks",
|
|
||||||
"tia": "thanks in advance",
|
|
||||||
"tla": "three-letter arconym",
|
|
||||||
"ttfn": "ta ta for now",
|
|
||||||
"ttyl": "talk to you later",
|
|
||||||
"wb": "welcome back",
|
|
||||||
"wfm": "works for me",
|
|
||||||
"wtf": "what the fuck?!",
|
|
||||||
"wtg": "way to go!",
|
|
||||||
"xfer": "transfer",
|
|
||||||
"ymmv": "your mileage may vary",}
|
|
||||||
70
acronyms_expander/acronyms.py
Normal file
70
acronyms_expander/acronyms.py
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
DEFAULT_DATA = {
|
||||||
|
"afaik": "as far as I know",
|
||||||
|
"afaict": "as far as I can tell",
|
||||||
|
"afk": "away from keyboard",
|
||||||
|
"atm": "at the moment",
|
||||||
|
"bbiab": "be back in a bit",
|
||||||
|
"bbiaf": "be back in a few (minutes)",
|
||||||
|
"bbl": "be back later",
|
||||||
|
"bbs": "be back soon",
|
||||||
|
"b/c": "because",
|
||||||
|
"bf": "boyfriend",
|
||||||
|
"bfo": "blinding flash of the obvious",
|
||||||
|
"brb": "be right back",
|
||||||
|
"bsod": "blue screen of death",
|
||||||
|
"btw": "by the way",
|
||||||
|
"ciao": "Italian for goodbye",
|
||||||
|
"ctrn": "can't talk right now",
|
||||||
|
"cul8r": "see you later",
|
||||||
|
"cya": "see ya",
|
||||||
|
"dhtb": "don't have the bandwidth",
|
||||||
|
"f2f": "face to face",
|
||||||
|
"fubar": "fucked up beyond all recognition",
|
||||||
|
"fwiw": "for what it's worth",
|
||||||
|
"fyi": "for your information",
|
||||||
|
"iam": "in a meeting",
|
||||||
|
"ianal": "I am not a lawyer",
|
||||||
|
"ihmb": "I hate my boss",
|
||||||
|
"iirc": "if I recall correctly",
|
||||||
|
"imho": "in my humble opinion",
|
||||||
|
"imo": "in my opinion",
|
||||||
|
"iow": "in other words",
|
||||||
|
"irl": "in real life",
|
||||||
|
"<g>": "grin",
|
||||||
|
"*g*": "grin",
|
||||||
|
"gf": "girlfriend",
|
||||||
|
"gmta": "great minds think alike",
|
||||||
|
"g2g": "got to go",
|
||||||
|
"jid": "jabber identifier",
|
||||||
|
"j/k": "just kidding",
|
||||||
|
"ok": "okay",
|
||||||
|
"lol": "laugh out loud",
|
||||||
|
"l8r": "later",
|
||||||
|
"msg": "message",
|
||||||
|
"n/m": "never mind",
|
||||||
|
"n/p": "no problem",
|
||||||
|
"oAo": "over and out!",
|
||||||
|
"omg": "oh my god",
|
||||||
|
"oob": "out of band",
|
||||||
|
"otoh": "on the other hand",
|
||||||
|
"oww": "oops, wrong window!",
|
||||||
|
"otp": "on the phone",
|
||||||
|
"pita": "pain in the ass",
|
||||||
|
"pov": "point of view",
|
||||||
|
"pw": "password",
|
||||||
|
"rotfl": "rolling on the floor laughing",
|
||||||
|
"rsn": "real soon now",
|
||||||
|
"rtfm": "read the friendly manual",
|
||||||
|
"slap": "sounds like a plan",
|
||||||
|
"thx": "thanks",
|
||||||
|
"tia": "thanks in advance",
|
||||||
|
"tla": "three-letter arconym",
|
||||||
|
"ttfn": "ta ta for now",
|
||||||
|
"ttyl": "talk to you later",
|
||||||
|
"wb": "welcome back",
|
||||||
|
"wfm": "works for me",
|
||||||
|
"wtf": "what the fuck?!",
|
||||||
|
"wtg": "way to go!",
|
||||||
|
"xfer": "transfer",
|
||||||
|
"ymmv": "your mileage may vary",
|
||||||
|
}
|
||||||
@@ -1,114 +1,124 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# Copyright (C) 2008 Mateusz Biliński <mateusz AT bilinski.it>
|
||||||
|
# Copyright (C) 2018 Philipp Hörist <philipp AT hoerist.com>
|
||||||
|
#
|
||||||
|
# This file is part of Acronyms Expander.
|
||||||
|
#
|
||||||
|
# Acronyms Expander is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published
|
||||||
|
# by the Free Software Foundation; version 3 only.
|
||||||
|
#
|
||||||
|
# Acronyms Expander is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with Acronyms Expander. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
## This file is part of Gajim.
|
import json
|
||||||
##
|
import logging
|
||||||
## Gajim is free software; you can redistribute it and/or modify
|
from pathlib import Path
|
||||||
## it under the terms of the GNU General Public License as published
|
|
||||||
## by the Free Software Foundation; version 3 only.
|
|
||||||
##
|
|
||||||
## Gajim is distributed in the hope that it will be useful,
|
|
||||||
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
## GNU General Public License for more details.
|
|
||||||
##
|
|
||||||
## You should have received a copy of the GNU General Public License
|
|
||||||
## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
##
|
|
||||||
|
|
||||||
'''
|
from gi.repository import GLib
|
||||||
Acronyms expander plugin.
|
|
||||||
|
|
||||||
:author: Mateusz Biliński <mateusz@bilinski.it>
|
from gajim.common import configpaths
|
||||||
:since: 9th June 2008
|
|
||||||
:copyright: Copyright (2008) Mateusz Biliński <mateusz@bilinski.it>
|
|
||||||
:license: GPL
|
|
||||||
'''
|
|
||||||
|
|
||||||
import os
|
|
||||||
|
|
||||||
from gi.repository import GObject
|
|
||||||
|
|
||||||
from gajim.plugins import GajimPlugin
|
from gajim.plugins import GajimPlugin
|
||||||
from gajim.plugins.helpers import log, log_calls
|
from gajim.plugins.plugins_i18n import _
|
||||||
|
|
||||||
|
from acronyms_expander.acronyms import DEFAULT_DATA
|
||||||
|
|
||||||
|
log = logging.getLogger('gajim.plugin_system.acronyms')
|
||||||
|
|
||||||
# Since Gajim 1.1.0 _() has to be imported
|
|
||||||
try:
|
|
||||||
from gajim.common.i18n import _
|
|
||||||
except ImportError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
class AcronymsExpanderPlugin(GajimPlugin):
|
class AcronymsExpanderPlugin(GajimPlugin):
|
||||||
|
|
||||||
@log_calls('AcronymsExpanderPlugin')
|
|
||||||
def init(self):
|
def init(self):
|
||||||
self.description = _('Replaces acronyms (or other strings) '
|
self.description = _('Replaces acronyms (or other strings) '
|
||||||
'with given expansions/substitutes.')
|
'with given expansions/substitutes.')
|
||||||
self.config_dialog = None
|
self.config_dialog = None
|
||||||
|
|
||||||
self.gui_extension_points = {
|
self.gui_extension_points = {
|
||||||
'chat_control_base': (self.connect_with_chat_control_base,
|
'chat_control_base': (self._connect, self._disconnect)
|
||||||
self.disconnect_from_chat_control_base)
|
|
||||||
}
|
}
|
||||||
|
self._invoker = ' '
|
||||||
|
self._acronyms = self._load_acronyms()
|
||||||
|
self._replace_in_progress = False
|
||||||
|
self._handler_ids = {}
|
||||||
|
|
||||||
self.config_default_values = {
|
@staticmethod
|
||||||
'INVOKER': (' ', ''),
|
def _load_acronyms():
|
||||||
'ACRONYMS': ({'/slap': '/me slaps',
|
try:
|
||||||
'PS-': 'plug-in system',
|
path = Path(configpaths.get('PLUGINS_DATA')) / 'acronyms'
|
||||||
'G-': 'Gajim',
|
except KeyError:
|
||||||
'GNT-': 'https://dev.gajim.org/gajim/gajim/issues',
|
# PLUGINS_DATA was added in 1.0.99.1
|
||||||
'GW-': 'https://dev.gajim.org/gajim/gajim/wikis/home',
|
return DEFAULT_DATA
|
||||||
},
|
|
||||||
''),
|
|
||||||
}
|
|
||||||
if 'ACRONYMS' not in self.config:
|
|
||||||
myAcronyms = self.get_own_acronyms_list()
|
|
||||||
self.config['ACRONYMS'].update(myAcronyms)
|
|
||||||
|
|
||||||
@log_calls('AcronymsExpanderPlugin')
|
if not path.exists():
|
||||||
def get_own_acronyms_list(self):
|
return DEFAULT_DATA
|
||||||
data_file = self.local_file_path('acronyms')
|
|
||||||
if not os.path.isfile(data_file):
|
with open(path / 'acronyms', 'r') as file:
|
||||||
return {}
|
acronyms = json.load(file)
|
||||||
data = open(data_file, 'r', encoding='utf-8')
|
|
||||||
acronyms = eval(data.read())
|
|
||||||
data.close()
|
|
||||||
return acronyms
|
return acronyms
|
||||||
|
|
||||||
@log_calls('AcronymsExpanderPlugin')
|
@staticmethod
|
||||||
def textbuffer_live_acronym_expander(self, tb):
|
def _save_acronyms(acronyms):
|
||||||
"""
|
path = Path(configpaths.get('PLUGINS_DATA')) / 'acronyms'
|
||||||
@param tb gtk.TextBuffer
|
with open(path / 'acronyms', 'w') as file:
|
||||||
"""
|
json.dump(acronyms, file)
|
||||||
#assert isinstance(tb,gtk.TextBuffer)
|
|
||||||
ACRONYMS = self.config['ACRONYMS']
|
|
||||||
INVOKER = self.config['INVOKER']
|
|
||||||
t = tb.get_text(tb.get_start_iter(), tb.get_end_iter(), True)
|
|
||||||
#log.debug('%s %d'%(t, len(t)))
|
|
||||||
if t and t[-1] == INVOKER:
|
|
||||||
#log.debug('changing msg text')
|
|
||||||
base, sep, head=t[:-1].rpartition(INVOKER)
|
|
||||||
log.debug('%s | %s | %s'%(base, sep, head))
|
|
||||||
if head in ACRONYMS:
|
|
||||||
head = ACRONYMS[head]
|
|
||||||
#log.debug('head: %s'%(head))
|
|
||||||
t = ''.join((base, sep, head, INVOKER))
|
|
||||||
#log.debug("setting text: '%s'"%(t))
|
|
||||||
GObject.idle_add(tb.set_text, t)
|
|
||||||
|
|
||||||
@log_calls('AcronymsExpanderPlugin')
|
def _on_buffer_changed(self, _textview, buffer_):
|
||||||
def connect_with_chat_control_base(self, chat_control):
|
if self._replace_in_progress:
|
||||||
d = {}
|
return
|
||||||
tv = chat_control.msg_textview
|
|
||||||
tb = tv.get_buffer()
|
|
||||||
h_id = tb.connect('changed', self.textbuffer_live_acronym_expander)
|
|
||||||
d['h_id'] = h_id
|
|
||||||
|
|
||||||
chat_control.acronyms_expander_plugin_data = d
|
if buffer_.get_char_count() < 2:
|
||||||
|
return
|
||||||
|
# Get iter at cursor
|
||||||
|
insert_iter = buffer_.get_iter_at_mark(buffer_.get_insert())
|
||||||
|
|
||||||
return True
|
if insert_iter.get_offset() < 2:
|
||||||
|
# We need at least 2 chars and an invoker
|
||||||
|
return
|
||||||
|
|
||||||
@log_calls('AcronymsExpanderPlugin')
|
# Get last char
|
||||||
def disconnect_from_chat_control_base(self, chat_control):
|
insert_iter.backward_char()
|
||||||
d = chat_control.acronyms_expander_plugin_data
|
if insert_iter.get_char() != self._invoker:
|
||||||
tv = chat_control.msg_textview
|
log.debug('"%s" not an invoker', insert_iter.get_char())
|
||||||
tv.get_buffer().disconnect(d['h_id'])
|
return
|
||||||
|
|
||||||
|
# Get to the start of the last word
|
||||||
|
word_start_iter = insert_iter.copy()
|
||||||
|
word_start_iter.backward_word_start()
|
||||||
|
|
||||||
|
# Get last word and cut invoker
|
||||||
|
last_word = word_start_iter.get_slice(insert_iter).strip()
|
||||||
|
|
||||||
|
substitute = self._acronyms.get(last_word)
|
||||||
|
if substitute is None:
|
||||||
|
log.debug('%s not an acronym', last_word)
|
||||||
|
return
|
||||||
|
|
||||||
|
# Replace
|
||||||
|
word_end_iter = word_start_iter.copy()
|
||||||
|
word_end_iter.forward_word_end()
|
||||||
|
GLib.idle_add(self._replace_text,
|
||||||
|
buffer_,
|
||||||
|
word_start_iter,
|
||||||
|
word_end_iter,
|
||||||
|
substitute)
|
||||||
|
|
||||||
|
def _replace_text(self, buffer_, start, end, substitute):
|
||||||
|
self._replace_in_progress = True
|
||||||
|
buffer_.delete(start, end)
|
||||||
|
buffer_.insert(start, substitute)
|
||||||
|
self._replace_in_progress = False
|
||||||
|
|
||||||
|
def _connect(self, chat_control):
|
||||||
|
textview = chat_control.msg_textview
|
||||||
|
handler_id = textview.connect('text-changed', self._on_buffer_changed)
|
||||||
|
self._handler_ids[id(textview)] = handler_id
|
||||||
|
|
||||||
|
def _disconnect(self, chat_control):
|
||||||
|
textview = chat_control.msg_textview
|
||||||
|
handler_id = self._handler_ids.get(id(textview))
|
||||||
|
if handler_id is not None:
|
||||||
|
textview.disconnect(handler_id)
|
||||||
|
del self._handler_ids[id(textview)]
|
||||||
|
|||||||
Reference in New Issue
Block a user