af2b6e2d27f3

Updates, remove airline and sparkup
[view raw] [browse files]
author Steve Losh <steve@stevelosh.com>
date Fri, 18 Aug 2017 12:08:23 -0400
parents b89b95f1cb1d
children 4acbaf543177
branches/tags (none)
files .hgsub .hgsubstate hgrc lispwords vim/vimrc weechat/python/autoload/wee_slack.py

Changes

--- a/.hgsub	Tue Jul 04 15:25:03 2017 +0000
+++ b/.hgsub	Fri Aug 18 12:08:23 2017 -0400
@@ -1,8 +1,6 @@
 mercurial/hg-prompt              = [hg]https://bitbucket.org/sjl/hg-prompt
 mercurial/templates              = [hg]https://bitbucket.org/sjl/mercurial-cli-templates
 vim/bundle/ack                   = [git]git://github.com/mileszs/ack.vim.git
-vim/bundle/airline               = [git]git://github.com/vim-airline/vim-airline.git
-vim/bundle/airline-themes        = [git]git://github.com/vim-airline/vim-airline-themes.git
 vim/bundle/argumentative         = [git]git://github.com/PeterRincker/vim-argumentative.git
 vim/bundle/badwolf               = [hg]https://bitbucket.org/sjl/badwolf/
 vim/bundle/bencode               = [hg]https://bitbucket.org/sjl/vim-bencode/
@@ -33,7 +31,6 @@
 vim/bundle/securemodelines       = [git]git://github.com/ciaranm/securemodelines.git
 vim/bundle/sexp                  = [git]git://github.com/guns/vim-sexp.git
 vim/bundle/shaderhighlight       = [git]git://github.com/vim-scripts/ShaderHighLight.git
-vim/bundle/sparkup               = [git]git://github.com/tristen/vim-sparkup.git
 vim/bundle/splice                = [hg]https://bitbucket.org/sjl/splice.vim
 vim/bundle/strftimedammit        = [hg]https://bitbucket.org/sjl/strftimedammit.vim/
 vim/bundle/surround              = [git]git://github.com/tpope/vim-surround.git
--- a/.hgsubstate	Tue Jul 04 15:25:03 2017 +0000
+++ b/.hgsubstate	Fri Aug 18 12:08:23 2017 -0400
@@ -1,17 +1,15 @@
 5334581e231a5167d03689ff47b3a6fdf082011c mercurial/hg-prompt
 1fc4a9fbead7e0acc4c828b346f3be2658ec3df9 mercurial/templates
 f183a345a0c10caed7684d07dabae33e007c7590 vim/bundle/ack
-168dd7970a95c0c5049fec0b101b7f53b6a22469 vim/bundle/airline
-a59cea9cae61654d7ba98ef100e3e8883c4b4022 vim/bundle/airline-themes
 6c4663589e73e21e77a9ea8403dcf2bf6cf9c11c vim/bundle/argumentative
-a6f651fa86068b8edb6799c9979a71e40caa3b42 vim/bundle/badwolf
+451b8111344a3a8117996f4e32b6a255b629f87b vim/bundle/badwolf
 2975b6f50397cc4912f04e3986906eca8fa441e7 vim/bundle/bencode
 a4d79fc208764917cb58e2aed6fbaeb5e3356d33 vim/bundle/clam
 f1c53e290b16885c2eb3fc96e57d9984b627f735 vim/bundle/clojure-static
 dc349bb7d30f713d770fc1fa0fe209e6aab82dc8 vim/bundle/commentary
 c6d1fc5e58d689bfb104ff336aeb89d9ef1b48e2 vim/bundle/ctrlp
 38487bbec8ba50834e257940b357de03991fa8f9 vim/bundle/delimitmate
-ffbd5eb50c9daf67657b87fd767d1801ac9a15a7 vim/bundle/dispatch
+6dd4480388e4727dfe5c723484c500e03b429c28 vim/bundle/dispatch
 1c75b56ceb96a6e7fb6708ae96ab63b3023bab2f vim/bundle/fireplace
 935a2cccd3065b1322fb2235285d42728600afdf vim/bundle/fugitive
 127d706f2def96876605e6bd5d366c973cb8e406 vim/bundle/gdl
@@ -25,7 +23,7 @@
 528e111b9fa32452366f382d50e998536d3ded85 vim/bundle/miniyank
 a1433c485eb254838c1db52e087d5ec4d1e77cfd vim/bundle/nerdtree
 160b717feddd46bfd580bf23198c92fd039c4d2e vim/bundle/omnisharp-vim
-5ed3bf0e4d0f1d9280ce430a089ae1ebadf4a559 vim/bundle/paredit
+f506af01e84e53643e0760b7f43c74069ce16c85 vim/bundle/paredit
 1a436f7d875b4ec630da081b041c73264235c7e7 vim/bundle/pgsql
 fd70ac2ab74a91fb049cb8e82237c34d88354673 vim/bundle/python-mode
 eb8baa5428bde10ecc1cb14eed1d6e16f5f24695 vim/bundle/rainbow-parentheses
@@ -33,7 +31,6 @@
 10d6c6b52fcdd12f3ba457126f66fee4ccceec04 vim/bundle/securemodelines
 b4398689f7483b01684044ab6b55bf369744c9b3 vim/bundle/sexp
 e02c3e218c51c1e2ea1821a3fe412d4e09ca1502 vim/bundle/shaderhighlight
-0377b100382c19295b42018289fe8d42a7d57e80 vim/bundle/sparkup
 287437b3bb6c4f21b4ed98443ede19db2a5b979c vim/bundle/splice
 26fbdd7d1f1aa5600d2ebf39bbdd292c38aac16e vim/bundle/strftimedammit
 2d05440ad23f97a7874ebd9b5de3a0e65d25d85c vim/bundle/surround
@@ -42,5 +39,5 @@
 f6f2d6618a321f5b0065586a7bc934325fec81ab vim/bundle/targets
 5d5c71044880443035e07009497962feacb56b20 vim/bundle/vimtex
 bf3fd7f67e730f93765bd3c1cfcdb18fd4043521 vim/bundle/vitality
-ae313e04ebd1bb9d0434fb2e7c9e25d418aa5f0a vim/bundle/vlime
+9da28e2ecf954a705aa9f00f37e206ee7bc09101 vim/bundle/vlime
 6876fe38b33732cb124d415ffc4156f16da5e118 vim/bundle/windowswap
--- a/hgrc	Tue Jul 04 15:25:03 2017 +0000
+++ b/hgrc	Fri Aug 18 12:08:23 2017 -0400
@@ -3,6 +3,7 @@
 editor = nvim
 commitsubrepos = False
 ignore = ~/.hgignore
+paginate = never
 
 [extensions]
 transplant = 
@@ -250,7 +251,7 @@
           $HG commit `$HG root`/.hgignore -Am 'Add "$@" to .hgignore.'
 
 # Show in Vim
-vshow = !$HG show $@ | nvim -c ':AnsiEsc' -c 'setlocal buftype=nofile' -
+vshow = !$HG show $@ --color=never | nvim -c 'setlocal buftype=nofile ft=diff' -
 vdiff = !$HG diff -p --color=always $@ | nvim -c ':AnsiEsc' -c 'setlocal buftype=nofile' -
 
 # Ack for non-ignored files
--- a/lispwords	Tue Jul 04 15:25:03 2017 +0000
+++ b/lispwords	Fri Aug 18 12:08:23 2017 -0400
@@ -75,9 +75,10 @@
 
 ; cl-losh
 (1 recursively)
-(2 when-found if-found)
+(1 when-found if-found)
 (1 when-let*)
 (1 multiple-value-bind*)
+(1 do-repeat)
 
 ; qtools
 (1 qtenumcase)
@@ -94,3 +95,6 @@
 
 ; blt
 (1 key-case)
+
+; conspack
+(1 tracking-refs)
--- 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("&lt;", "<")
         text = text.replace("&gt;", ">")
         text = text.replace("&amp;", "&")
-        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: