--- a/vim/vimrc Tue Jul 04 15:25:03 2017 +0000
+++ b/vim/vimrc Fri Aug 18 12:08:23 2017 -0400
@@ -292,6 +292,9 @@
" Man
nnoremap M K
+" Clean up windows
+nnoremap - :wincmd =<cr>
+
" Toggle line numbers
nnoremap <leader>n :setlocal number!<cr>
@@ -421,9 +424,6 @@
" I never use l as a macro register anyway.
nnoremap ql gqq
-" Easier linewise reselection of what you just pasted.
-nnoremap <leader>V V`]
-
" Indent/dedent/autoindent what you just pasted.
nnoremap <lt>> V`]<
nnoremap ><lt> V`]>
@@ -544,6 +544,106 @@
nnoremap <leader>ev :vsplit $MYVIMRC<cr>
" }}}
+" Status Line ------------------------------------------------------------- {{{
+
+function! StatusLineMode()
+ let mode = mode()
+
+ if mode == "n"
+ call GoodWolfHL('GWStatusLineMode', 'coal', 'lime', 'bold')
+ call GoodWolfHL('GWStatusLineModeX', 'lime', 'deepergravel')
+ call GoodWolfHL('GWStatusLineModeY', 'lime', 'deepgravel')
+ return "NORMAL"
+ elseif mode == "no"
+ call GoodWolfHL('GWStatusLineMode', 'coal', 'lime', 'bold')
+ call GoodWolfHL('GWStatusLineModeX', 'lime', 'deepergravel')
+ call GoodWolfHL('GWStatusLineModeY', 'lime', 'deepgravel')
+ return "OPERATOR"
+ elseif mode == "V" || mode == ""
+ call GoodWolfHL('GWStatusLineMode', 'coal', 'dirtyblonde', 'bold')
+ call GoodWolfHL('GWStatusLineModeX', 'dirtyblonde', 'deepergravel')
+ call GoodWolfHL('GWStatusLineModeY', 'dirtyblonde', 'deepgravel')
+ return "VISUAL"
+ elseif mode == "s" || mode == "S" || mode == ""
+ call GoodWolfHL('GWStatusLineMode', 'coal', 'dirtyblonde', 'bold')
+ call GoodWolfHL('GWStatusLineModeX', 'dirtyblonde', 'deepergravel')
+ call GoodWolfHL('GWStatusLineModeY', 'dirtyblonde', 'deepgravel')
+ return "SELECT"
+ elseif mode == "i"
+ call GoodWolfHL('GWStatusLineMode', 'coal', 'tardis', 'bold')
+ call GoodWolfHL('GWStatusLineModeX', 'tardis', 'deepergravel')
+ call GoodWolfHL('GWStatusLineModeY', 'tardis', 'deepgravel')
+ return "INSERT"
+ elseif mode == "r" || mode == "Rv"
+ call GoodWolfHL('GWStatusLineMode', 'coal', 'taffy', 'bold')
+ call GoodWolfHL('GWStatusLineModeX', 'taffy', 'deepergravel')
+ call GoodWolfHL('GWStatusLineModeY', 'taffy', 'deepgravel')
+ return "REPLACE"
+ elseif mode == "t"
+ call GoodWolfHL('GWStatusLineMode', 'coal', 'tardis', 'bold')
+ call GoodWolfHL('GWStatusLineModeX', 'tardis', 'deepergravel')
+ call GoodWolfHL('GWStatusLineModeY', 'tardis', 'deepgravel')
+ return "TERMINAL"
+ else
+ call GoodWolfHL('GWStatusLineMode', 'coal', 'lime', 'bold')
+ call GoodWolfHL('GWStatusLineModeX', 'lime', 'deepergravel')
+ call GoodWolfHL('GWStatusLineModeY', 'lime', 'deepgravel')
+ return "OTHER"
+ endif
+endfunction
+
+function! SetStatusLine(winnr)
+ let s = ""
+
+ if a:winnr == winnr()
+ let s .= "%#GWStatusLineMode#"
+ let s .= " "
+ let s .= "%{StatusLineMode()}"
+ let s .= " "
+ let s .= "%#GWStatusLineModeX#"
+ let s .= "⮀ "
+
+ let s .= "%f"
+ let s .= " %m%r%h%w"
+ let s .= "%="
+
+ let s .= " %y"
+ let s .= " \[%{&fileencoding?&fileencoding:&encoding}/%{&fileformat}\] "
+
+ let s .= "%#GWStatusLineModeY#"
+ let s .= "⮂"
+ let s .= "%#GWStatusLineMode#"
+ let s .= " %3c ⭡ "
+ let s .= "%l" " Current line
+ let s .= "/"
+ let s .= "%L" " Total lines
+ let s .= " "
+ else
+ let s .= "%#StatusLineNC#"
+ let s .= "%f"
+ let s .= " %m%r%h%w"
+ let s .= "%="
+ let s .= " %y"
+ let s .= " \[%{&fileencoding?&fileencoding:&encoding}/%{&fileformat}\] "
+ endif
+
+ return s
+endfunction
+
+function! RefreshStatusLine()
+ for nr in range(1, winnr('$'))
+ call setwinvar(nr, '&statusline', '%!SetStatusLine(' . nr . ')')
+ endfor
+endfunction
+
+augroup statusline
+ autocmd!
+ autocmd VimEnter,WinEnter,BufWinEnter * call RefreshStatusLine()
+augroup END
+
+" set statusline+=%=
+
+" }}}
" Searching and movement -------------------------------------------------- {{{
" Use sane regexes.
@@ -938,9 +1038,35 @@
call winrestview(view)
endfunction "}}}
+
function! SelectToplevelLispForm() "{{{
execute "normal v\<Plug>(sexp_outer_top_list)"
endfunction "}}}
+function! SelectLispExpression() "{{{
+ execute "normal v\<Plug>(sexp_inner_element)"
+endfunction "}}}
+
+function! HyperspecLispExpression(vertical) "{{{
+ let z = @z
+
+ call SelectLispExpression()
+ normal! gv"zy
+
+ if a:vertical
+ vnew
+ else
+ new
+ endif
+
+ set buftype=nofile
+
+ call termopen('clhs ' . @z)
+
+ normal! i
+
+ let @z = z
+endfunction "}}}
+
function! SendToplevelLispForm() "{{{
let view = winsaveview()
@@ -1057,9 +1183,13 @@
" Misc mappings
au FileType lisp nnoremap <buffer> gi :call IndentToplevelLispForm()<cr>
+ au FileType lisp nnoremap <buffer> <localleader>h :call HyperspecLispExpression(0)<cr>
+ au FileType lisp nnoremap <buffer> <localleader>H :call HyperspecLispExpression(1)<cr>
au FileType lisp nnoremap <buffer> <silent> <localleader>q :call QuickloadLispSystem()<cr>
au FileType lisp nnoremap <buffer> <silent> <localleader>Q :call QuickloadLispPrompt()<cr>
au FileType lisp nnoremap <buffer> [] :call DuplicateLispForm()<cr>
+ au FileType lisp nnoremap <buffer> <localleader>( :call PareditToggle()<cr>
+ ")
" Navigate trees of sexps with arrows
au FileType lisp call s:vim_sexp_mappings()
@@ -1914,34 +2044,6 @@
let g:ackprg = 'ag --smart-case --nogroup --nocolor --column'
" }}}
-" Airline {{{
-
-if !exists('g:airline_symbols')
- let g:airline_symbols = {}
-endif
-
-let g:airline_theme='badwolf'
-
-let g:airline_theme_patch_func = 'AirlineThemePatch'
-function! AirlineThemePatch(palette)
- if g:airline_theme == 'badwolf'
- for colors in values(a:palette.inactive)
- let colors[2] = 15
- endfor
- endif
-endfunction
-
-let g:airline#extensions#syntastic#enabled = 0
-
-let g:airline_left_sep = '⮀'
-let g:airline_left_alt_sep = '⮁'
-let g:airline_right_sep = '⮂'
-let g:airline_right_alt_sep = '⮃'
-let g:airline_symbols.branch = '⭠'
-let g:airline_symbols.readonly = '⭤'
-let g:airline_symbols.linenr = '⭡'
-
-" }}}
" Clam {{{
nnoremap ! :Clam<space>
@@ -2395,11 +2497,6 @@
endfunction
" }}}
-" Sparkup {{{
-
-let g:sparkupNextMapping = '<c-s>'
-
-"}}}
" Supertab {{{
let g:SuperTabDefaultCompletionType = "<c-n>"
@@ -2461,8 +2558,8 @@
let g:vlime_window_settings = {
\ "sldb": {
- \ "pos": "topleft",
- \ "vertical": v:true
+ \ "pos": "belowright",
+ \ "vertical": v:false
\ },
\ "xref": {
\ "pos": "belowright",
@@ -2471,8 +2568,11 @@
\ },
\ "repl": {
\ "pos": "belowright",
- \ "size": 80,
- \ "vertical": v:true
+ \ "vertical": v:false
+ \ },
+ \ "inspector": {
+ \ "pos": "belowright",
+ \ "vertical": v:false
\ },
\ "arglist": {
\ "pos": "topleft",
@@ -2482,7 +2582,7 @@
\ }
let g:vlime_compiler_policy = {
- \ "DEBUG": 3,
+ \ "DEBUG": 2,
\ "SPEED": 1
\ }
@@ -2490,6 +2590,7 @@
call vlime#plugin#CloseWindow("preview")
call vlime#plugin#CloseWindow("notes")
call vlime#plugin#CloseWindow("xref")
+ wincmd =
endfunction
function! MapVlimeKeys()
@@ -2500,7 +2601,7 @@
augroup CustomVlimeInputBuffer
autocmd!
" autocmd FileType vlime_input inoremap <silent> <buffer> <tab> <c-r>=VlimeKey("tab")<cr>
- autocmd FileType vlime_input setlocal omnifunc=VlimeCompleteFunc
+ autocmd FileType vlime_input setlocal omnifunc=vlime#plugin#CompleteFunc
" autocmd FileType vlime_input setlocal indentexpr=VlimeCalcCurIndent()
autocmd FileType vlime_input inoremap <c-n> <c-x><c-o>
augroup end
@@ -2517,7 +2618,10 @@
au FileType lisp nnoremap <buffer> <localleader>f :call vlime#plugin#CompileFile(expand("%:p"))<cr>
au FileType lisp nnoremap <buffer> <localleader>S :call vlime#plugin#SendToREPL(vlime#ui#CurTopExpr())<cr>
au FileType lisp nnoremap <buffer> <localleader>i :call vlime#plugin#Inspect(vlime#ui#CurExprOrAtom())<cr>
- au FileType lisp nnoremap <buffer> M :call vlime#plugin#DocumentationSymbol(vlime#ui#CurOperator())<cr>
+ au FileType lisp nnoremap <buffer> M :call vlime#plugin#DocumentationSymbol(vlime#ui#CurAtom())<cr>
+
+ " Keys for the REPL
+ au FileType vlime_repl nnoremap <buffer> i :call vlime#ui#repl#InspectCurREPLPresentation()<cr>
" Universal keys, for all kinds of Vlime windows
au FileType lisp,vlime_repl,vlime_inspector,vlime_sldb,vlime_notes,vlime_xref,vlime_preview call MapVlimeKeys()
@@ -2531,6 +2635,9 @@
" Fix d
au FileType vlime_sldb nnoremap <buffer> <nowait> d :call vlime#ui#sldb#ShowFrameDetails()<cr>
+ " Fix s
+ au FileType vlime_sldb nnoremap <buffer> <nowait> s :call vlime#ui#sldb#StepCurOrLastFrame("step")<cr>
+
" Fix p
au FileType vlime_inspector nnoremap <buffer> p :call vlime#ui#inspector#InspectorPop()<cr>
augroup end
@@ -2640,6 +2747,27 @@
" nnoremap <leader>W :call ToggleDiffWhitespace()<CR>
" }}}
+" Virtualedit Toggle {{{
+
+set virtualedit=block
+let g:virtualeditallon = 0
+
+function! ToggleVirtualEdit()
+ if g:virtualeditallon
+ set virtualedit=block
+ let g:virtualeditallon = 0
+ else
+ set virtualedit=all
+ let g:virtualeditallon = 1
+ endif
+endfunc
+
+nnoremap <leader>V :call ToggleVirtualEdit()<cr>
+
+" TODO: Figure out the diffexpr shit necessary to make this buffer-local.
+" nnoremap <leader>W :call ToggleDiffWhitespace()<CR>
+
+" }}}
" Error Toggles {{{
command! ErrorsToggle call ErrorsToggle()
@@ -2681,7 +2809,7 @@
" nmap <silent> <f3> :LocationToggle<cr>
" }}}
-" Hg {{{
+" Hg (Mercurial) {{{
"
" \hc - hg commit
" \hd - hg diff
--- a/weechat/python/autoload/wee_slack.py Tue Jul 04 15:25:03 2017 +0000
+++ b/weechat/python/autoload/wee_slack.py Fri Aug 18 12:08:23 2017 -0400
@@ -150,6 +150,13 @@
return decode_from_utf8(orig_attr)
+##### Helpers
+
+def get_nick_color_name(nick):
+ info_name_prefix = "irc_" if int(weechat_version) < 0x1050000 else ""
+ return w.info_get(info_name_prefix + "nick_color_name", nick)
+
+
##### BEGIN NEW
IGNORED_EVENTS = [
@@ -1024,7 +1031,7 @@
if self.ws_url:
try:
ws = create_connection(self.ws_url, sslopt=sslopt_ca_certs)
- w.hook_fd(ws.sock._sock.fileno(), 1, 0, 0, "receive_ws_callback", self.get_team_hash())
+ self.hook = w.hook_fd(ws.sock._sock.fileno(), 1, 0, 0, "receive_ws_callback", self.get_team_hash())
ws.sock.setblocking(0)
self.ws = ws
# self.attach_websocket(ws)
@@ -1048,6 +1055,7 @@
self.connected = True
def set_disconnected(self):
+ w.unhook(self.hook)
self.connected = False
def set_reconnect_url(self, url):
@@ -1536,7 +1544,7 @@
def update_color(self):
if config.colorize_private_chats:
- self.color_name = w.info_get('irc_nick_color_name', self.name)
+ self.color_name = get_nick_color_name(self.name)
self.color = w.color(self.color_name)
else:
self.color = ""
@@ -1815,7 +1823,7 @@
def update_color(self):
# This will automatically be none/"" if the user has disabled nick
# colourization.
- self.color_name = w.info_get('nick_color_name', self.name)
+ self.color_name = get_nick_color_name(self.name)
self.color = w.color(self.color_name)
def formatted_name(self, prepend="", enable_color=True):
@@ -2430,6 +2438,17 @@
###### New module/global methods
+def render_formatting(text):
+ text = re.sub(r'(^| )\*([^*]+)\*([^a-zA-Z0-9_]|$)',
+ r'\1{}\2{}\3'.format(w.color(config.render_bold_as),
+ w.color('-' + config.render_bold_as)),
+ text)
+ text = re.sub(r'(^| )_([^_]+)_([^a-zA-Z0-9_]|$)',
+ r'\1{}\2{}\3'.format(w.color(config.render_italic_as),
+ w.color('-' + config.render_italic_as)),
+ text)
+ return text
+
def render(message_json, team, channel, force=False):
# If we already have a rendered version in the object, just return that.
@@ -2458,10 +2477,8 @@
text = text.replace("<", "<")
text = text.replace(">", ">")
text = text.replace("&", "&")
- text = re.sub(r'(^| )\*([^*]+)\*([^a-zA-Z0-9_]|$)',
- r'\1{}\2{}\3'.format(w.color('bold'), w.color('-bold')), text)
- text = re.sub(r'(^| )_([^_]+)_([^a-zA-Z0-9_]|$)',
- r'\1{}\2{}\3'.format(w.color('underline'), w.color('-underline')), text)
+ if message_json.get('mrkdwn', True):
+ text = render_formatting(text)
# if self.threads:
# text += " [Replies: {} Thread ID: {} ] ".format(len(self.threads), self.thread_id)
@@ -2477,7 +2494,11 @@
# function is only called on message send..
usernames = team.get_username_map()
channels = team.get_channel_map()
- message = message.replace('\x02', '*').replace('\x1F', '_').split(' ')
+ message = (message
+ .replace('\x02', '*')
+ .replace('\x1D', '_')
+ .replace('\x1F', config.map_underline_to)
+ .split(' '))
for item in enumerate(message):
targets = re.match('^\s*([@#])([\w.-]+[\w. -])(\W*)', item[1])
if targets and targets.groups()[0] == '@':
@@ -3210,39 +3231,114 @@
###### Config code
+Setting = collections.namedtuple('Setting', ['default', 'desc'])
class PluginConfig(object):
# Default settings.
- # These are in the (string) format that weechat expects; at __init__ time
- # this value will be used to set the default for any settings not already
- # defined, and then the real (python) values of the settings will be
- # extracted.
- # TODO: setting descriptions.
- settings = {
- 'colorize_private_chats': 'false',
- 'debug_mode': 'false',
- 'debug_level': '3',
- 'distracting_channels': '',
- 'show_reaction_nicks': 'false',
- 'slack_api_token': 'INSERT VALID KEY HERE!',
- 'slack_timeout': '20000',
- 'switch_buffer_on_join': 'true',
- 'trigger_value': 'false',
- 'unfurl_ignore_alt_text': 'false',
- 'record_events': 'false',
- 'thread_suffix_color': 'lightcyan',
- 'unhide_buffers_with_activity': 'false',
- 'short_buffer_names': 'false',
- 'channel_name_typing_indicator': 'true',
- 'background_load_all_history': 'false',
- 'never_away': 'false',
- 'server_aliases': '',
+ # These are, initially, each a (default, desc) tuple; the former is the
+ # default value of the setting, in the (string) format that weechat
+ # expects, and the latter is the user-friendly description of the setting.
+ # At __init__ time these values are extracted, the description is used to
+ # set or update the setting description for use with /help, and the default
+ # value is used to set the default for any settings not already defined.
+ # Following this procedure, the keys remain the same, but the values are
+ # the real (python) values of the settings.
+ default_settings = {
+ 'background_load_all_history': Setting(
+ default='false',
+ desc='Load history for each channel in the background as soon as it'
+ ' opens, rather than waiting for the user to look at it.'),
+ 'channel_name_typing_indicator': Setting(
+ default='true',
+ desc='Change the prefix of a channel from # to > when someone is'
+ ' typing in it. Note that this will (temporarily) affect the sort'
+ ' order if you sort buffers by name rather than by number.'),
+ 'colorize_private_chats': Setting(
+ default='false',
+ desc='Whether to use nick-colors in DM windows.'),
+ 'debug_mode': Setting(
+ default='false',
+ desc='Open a dedicated buffer for debug messages and start logging'
+ ' to it. How verbose the logging is depends on log_level.'),
+ 'debug_level': Setting(
+ default='3',
+ desc='Show only this level of debug info (or higher) when'
+ ' debug_mode is on. Lower levels -> more messages.'),
+ 'distracting_channels': Setting(
+ default='',
+ desc='List of channels to hide.'),
+ 'map_underline_to': Setting(
+ default='_',
+ desc='When sending underlined text to slack, use this formatting'
+ ' character for it. The default ("_") sends it as italics. Use'
+ ' "*" to send bold instead.'),
+ 'never_away': Setting(
+ default='false',
+ desc='Poke Slack every five minutes so that it never marks you "away".'),
+ 'record_events': Setting(
+ default='false',
+ desc='Log all traffic from Slack to disk as JSON.'),
+ 'render_bold_as': Setting(
+ default='bold',
+ desc='When receiving bold text from Slack, render it as this in weechat.'),
+ 'render_italic_as': Setting(
+ default='italic',
+ desc='When receiving bold text from Slack, render it as this in weechat.'
+ ' If your terminal lacks italic support, consider using "underline" instead.'),
+ 'server_aliases': Setting(
+ default='',
+ desc='A comma separated list of `subdomain:alias` pairs. The alias'
+ ' will be used instead of the actual name of the slack (in buffer'
+ ' names, logging, etc). E.g `work:no_fun_allowed` would make your'
+ ' work slack show up as `no_fun_allowed` rather than `work.slack.com`.'),
+ 'short_buffer_names': Setting(
+ default='false',
+ desc='Use `foo.#channel` rather than `foo.slack.com.#channel` as the'
+ ' internal name for Slack buffers. Overrides server_aliases.'),
+ 'show_reaction_nicks': Setting(
+ default='false',
+ desc='Display the name of the reacting user(s) alongside each reactji.'),
+ 'slack_api_token': Setting(
+ default='INSERT VALID KEY HERE!',
+ desc='List of Slack API tokens, one per Slack instance you want to'
+ ' connect to. See the README for details on how to get these.'),
+ 'slack_timeout': Setting(
+ default='20000',
+ desc='How long (ms) to wait when communicating with Slack.'),
+ 'switch_buffer_on_join': Setting(
+ default='true',
+ desc='When /joining a channel, automatically switch to it as well.'),
+ 'thread_suffix_color': Setting(
+ default='lightcyan',
+ desc='Color to use for the [thread: XXX] suffix on messages that'
+ ' have threads attached to them.'),
+ 'unfurl_ignore_alt_text': Setting(
+ default='false',
+ desc='When displaying ("unfurling") links to channels/users/etc,'
+ ' ignore the "alt text" present in the message and instead use the'
+ ' canonical name of the thing being linked to.'),
+ 'unhide_buffers_with_activity': Setting(
+ default='false',
+ desc='When activity occurs on a buffer, unhide it even if it was'
+ ' previously hidden (whether by the user or by the'
+ ' distracting_channels setting).'),
}
# Set missing settings to their defaults. Load non-missing settings from
# weechat configs.
def __init__(self):
+ self.settings = {}
+ # Set all descriptions, replace the values in the dict with the
+ # default setting value rather than the (setting,desc) tuple.
+ # Use items() rather than iteritems() so we don't need to worry about
+ # invalidating the iterator.
+ for key, (default, desc) in self.default_settings.items():
+ w.config_set_desc_plugin(key, desc)
+ self.settings[key] = default
+
+ # Migrate settings from old versions of Weeslack...
self.migrate()
+ # ...and then set anything left over from the defaults.
for key, default in self.settings.iteritems():
if not w.config_get_plugin(key):
w.config_set_plugin(key, default)
@@ -3274,6 +3370,19 @@
def get_boolean(self, key):
return w.config_string_to_boolean(w.config_get_plugin(key))
+ def get_string(self, key):
+ return w.config_get_plugin(key)
+
+ def get_int(self, key):
+ return int(w.config_get_plugin(key))
+
+ get_debug_level = get_int
+ get_map_underline_to = get_string
+ get_render_bold_as = get_string
+ get_render_italic_as = get_string
+ get_slack_timeout = get_int
+ get_thread_suffix_color = get_string
+
def get_distracting_channels(self, key):
return [x.strip() for x in w.config_get_plugin(key).split(',')]
@@ -3289,15 +3398,6 @@
else:
return token
- def get_thread_suffix_color(self, key):
- return w.config_get_plugin("thread_suffix_color")
-
- def get_debug_level(self, key):
- return int(w.config_get_plugin(key))
-
- def get_slack_timeout(self, key):
- return int(w.config_get_plugin(key))
-
def migrate(self):
"""
This is to migrate the extension name from slack_extension to slack
@@ -3349,8 +3449,8 @@
if w.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION, SCRIPT_LICENSE,
SCRIPT_DESC, "script_unloaded", ""):
- version = w.info_get("version_number", "") or 0
- if int(version) < 0x1030000:
+ weechat_version = w.info_get("version_number", "") or 0
+ if int(weechat_version) < 0x1030000:
w.prnt("", "\nERROR: Weechat version 1.3+ is required to use {}.\n\n".format(SCRIPT_NAME))
else: