HackerTrans
TopNewTrendsCommentsPastAskShowJobs

qazxcvbnm

no profile record

Submissions

Graphical Emacs Browser

github.com
28 points·by qazxcvbnm·há 3 meses·2 comments

comments

qazxcvbnm
·há 3 meses·discuss
Interestingly, just the same day I find that xwidgets isn't dead anymore (https://github.com/emacs-mirror/emacs/commit/4e855f90d1b1c39...); life is funny!
qazxcvbnm
·há 3 meses·discuss
Finally found a working graphical Emacs browser! I've been looking for just this since webkit widgets died. In my experience on macOS, EAF was very buggy (plus spawning an ugly extra Python window).

This comes with a lovely transient menu even!

Installation was quite smooth, works just as advertised. Still have some hiccups (link hinting often requires multiple calls to detect; events get stuck after pressing Google AI Search popup; on first setup displays what appears to be an undismissable chromium video cast popup; consumes more CPU than ideal), but altogether something I definitely can work with!
qazxcvbnm
·há 4 meses·discuss
My goodness, how so thoughtful Emacs Solo is!
qazxcvbnm
·há 4 meses·discuss
The new Emacs features sound great! (We have native window management finally)

I wish we would someday be able to edit in xref too, wgrep having landed in Emacs 30 (especially since project.el grep goes to xref by default).

By the way, anyone more informed know about any work on getting a graphical browser to work on latest Emacs, now that webkit xwidgets is dead for Emacs 30+? (Have tried EAF; extremely buggy on Mac)
qazxcvbnm
·há 5 meses·discuss
M-n, M-p. M-r for searching on past commands. C-c c-n/C-p for next/previous prompt. C-c C-r to scroll to focus on output.

Having switched recently to Emacs, my current issue is how to get Emacs shell history saved properly for my other shell buffers, and getting completions from shell (not Emacs) to work, planning to try MisTTY soon.
qazxcvbnm
·há 7 meses·discuss
By the way, anyone have experience using emacs to analyse and visualise data (think spreadsheets and charts)? I’d really like to be able to use it to view any sort of data I happen to have.
qazxcvbnm
·há 9 meses·discuss
An uninformed question: If the network is fully composed of 1x1 convolutions, doesn’t that mean no information mixing between pixels occur? Would that not imply that each pixel is independent of each other? How can that not lead to incoherent results?
qazxcvbnm
·há 11 meses·discuss
When things aren’t ticking perfectly for Synology their software can be kind of weird. Sometimes after power failures, some disks get corrupted and… you simply can’t log in to the Synology UI during this time (unless you “synobootseq --set-boot-done”, why, of course) for an unspecified number of hours.

Their custom software has its quirks (eg scp doesn’t work unless you apply the -O flag, for “security” reasons), and the quirks change sometimes after updates.
qazxcvbnm
·ano passado·discuss
And batching
qazxcvbnm
·ano passado·discuss
When you get to using [count]g[something] and g[count][something] and <C-@>[count]g[something] etc a lot, you start getting a bit confused about where you need to put the count to make things work. So you can make putting the count anywhere work; now, don't worry and just start pressing g or <C-@>g for window actions, and put a count if you realise you need it:

    map <expr> <C-@>1 Termcountmap(1, "")
    map <expr> <C-@>2 Termcountmap(2, "")
    map <expr> <C-@>3 Termcountmap(3, "")
    map <expr> <C-@>4 Termcountmap(4, "")
    map <expr> <C-@>5 Termcountmap(5, "")
    map <expr> <C-@>6 Termcountmap(6, "")
    map <expr> <C-@>7 Termcountmap(7, "")
    map <expr> <C-@>8 Termcountmap(8, "")
    map <expr> <C-@>9 Termcountmap(9, "")
    map! <expr> <C-@>1 Termcountmap(1, '<Esc>')
    map! <expr> <C-@>2 Termcountmap(2, '<Esc>')
    map! <expr> <C-@>3 Termcountmap(3, '<Esc>')
    map! <expr> <C-@>4 Termcountmap(4, '<Esc>')
    map! <expr> <C-@>5 Termcountmap(5, '<Esc>')
    map! <expr> <C-@>6 Termcountmap(6, '<Esc>')
    map! <expr> <C-@>7 Termcountmap(7, '<Esc>')
    map! <expr> <C-@>8 Termcountmap(8, '<Esc>')
    map! <expr> <C-@>9 Termcountmap(9, '<Esc>')
    tmap <expr> <C-@>1 Termcountmap(1, '<C-@>N')
    tmap <expr> <C-@>2 Termcountmap(2, '<C-@>N')
    tmap <expr> <C-@>3 Termcountmap(3, '<C-@>N')
    tmap <expr> <C-@>4 Termcountmap(4, '<C-@>N')
    tmap <expr> <C-@>5 Termcountmap(5, '<C-@>N')
    tmap <expr> <C-@>6 Termcountmap(6, '<C-@>N')
    tmap <expr> <C-@>7 Termcountmap(7, '<C-@>N')
    tmap <expr> <C-@>8 Termcountmap(8, '<C-@>N')
    tmap <expr> <C-@>9 Termcountmap(9, '<C-@>N')

    function! Termcountmap(initcount, normalkeys)
     let termcount = a:initcount
     while 1
      try
       let char = getchar()
      catch /^Vim:Interrupt$/
       return ""
       endtry
    
      if type(char) == 0
       let char = nr2char(char)
       endif
    
      if char == '0'
       let termcount = termcount * 10
      elseif char == '1'
       let termcount = termcount * 10 + 1
      elseif char == '2'
       let termcount = termcount * 10 + 2
      elseif char == '3'
       let termcount = termcount * 10 + 3
      elseif char == '4'
       let termcount = termcount * 10 + 4
      elseif char == '5'
       let termcount = termcount * 10 + 5
      elseif char == '6'
       let termcount = termcount * 10 + 6
      elseif char == '7'
       let termcount = termcount * 10 + 7
      elseif char == '8'
       let termcount = termcount * 10 + 8
      elseif char == '9'
       let termcount = termcount * 10 + 9
      elseif char == 'g'
       return a:normalkeys .. termcount .. 'g'
      elseif char == "\<C-g>"
       return a:normalkeys .. termcount .. "\<C-@>\<C-g>"
      elseif char == 'w'
       return a:normalkeys .. termcount .. "\<C-@>w"
      elseif char == 'W'
       return a:normalkeys .. termcount .. "\<C-@>W"
      elseif char == 't'
       return a:normalkeys .. termcount .. "\<C-@>t"
      elseif char == 'b'
       return a:normalkeys .. termcount .. "\<C-@>b"
      else
       return a:normalkeys .. ":\<C-u>" .. termcount .. ' wincmd ' .. char .. "\<CR>\<C-l>"
       endif
    
      endwhile
     endfunction
    
    map <expr> g<C-@> <C-@>g
    
    map <expr> g1 Prefixcountmap (v:count * 10 + 1, "", 'g')
    map <expr> g2 Prefixcountmap (v:count * 10 + 2, "", 'g')
    map <expr> g3 Prefixcountmap (v:count * 10 + 3, "", 'g')
    map <expr> g4 Prefixcountmap (v:count * 10 + 4, "", 'g')
    map <expr> g5 Prefixcountmap (v:count * 10 + 5, "", 'g')
    map <expr> g6 Prefixcountmap (v:count * 10 + 6, "", 'g')
    map <expr> g7 Prefixcountmap (v:count * 10 + 7, "", 'g')
    map <expr> g8 Prefixcountmap (v:count * 10 + 8, "", 'g')
    map <expr> g9 Prefixcountmap (v:count * 10 + 9, "", 'g')
    tmap <expr> <c-@>g1 Prefixcountmap (v:count * 10 + 1, '<c-@>n', 'g')
    tmap <expr> <c-@>g2 Prefixcountmap (v:count * 10 + 2, '<c-@>n', 'g')
    tmap <expr> <c-@>g3 Prefixcountmap (v:count * 10 + 3, '<c-@>n', 'g')
    tmap <expr> <c-@>g4 Prefixcountmap (v:count * 10 + 4, '<c-@>n', 'g')
    tmap <expr> <c-@>g5 Prefixcountmap (v:count * 10 + 5, '<c-@>n', 'g')
    tmap <expr> <c-@>g6 Prefixcountmap (v:count * 10 + 6, '<c-@>n', 'g')
    tmap <expr> <c-@>g7 Prefixcountmap (v:count * 10 + 7, '<c-@>n', 'g')
    tmap <expr> <c-@>g8 Prefixcountmap (v:count * 10 + 8, '<c-@>n', 'g')
    tmap <expr> <c-@>g9 Prefixcountmap (v:count * 10 + 9, '<c-@>n', 'g')
    
    map <expr> <C-@><C-g>1 Prefixcountmap (v:count * 10 + 1, "", '<C-@><C-g>')
    map <expr> <C-@><C-g>2 Prefixcountmap (v:count * 10 + 2, "", '<C-@><C-g>')
    map <expr> <C-@><C-g>3 Prefixcountmap (v:count * 10 + 3, "", '<C-@><C-g>')
    map <expr> <C-@><C-g>4 Prefixcountmap (v:count * 10 + 4, "", '<C-@><C-g>')
    map <expr> <C-@><C-g>5 Prefixcountmap (v:count * 10 + 5, "", '<C-@><C-g>')
    map <expr> <C-@><C-g>6 Prefixcountmap (v:count * 10 + 6, "", '<C-@><C-g>')
    map <expr> <C-@><C-g>7 Prefixcountmap (v:count * 10 + 7, "", '<C-@><C-g>')
    map <expr> <C-@><C-g>8 Prefixcountmap (v:count * 10 + 8, "", '<C-@><C-g>')
    map <expr> <C-@><C-g>9 Prefixcountmap (v:count * 10 + 9, "", '<C-@><C-g>')
    map! <expr> <C-@><C-g>1 Prefixcountmap (v:count * 10 + 1, '<Esc>', '<C-@><C-g>')
    map! <expr> <C-@><C-g>2 Prefixcountmap (v:count * 10 + 2, '<Esc>', '<C-@><C-g>')
    map! <expr> <C-@><C-g>3 Prefixcountmap (v:count * 10 + 3, '<Esc>', '<C-@><C-g>')
    map! <expr> <C-@><C-g>4 Prefixcountmap (v:count * 10 + 4, '<Esc>', '<C-@><C-g>')
    map! <expr> <C-@><C-g>5 Prefixcountmap (v:count * 10 + 5, '<Esc>', '<C-@><C-g>')
    map! <expr> <C-@><C-g>6 Prefixcountmap (v:count * 10 + 6, '<Esc>', '<C-@><C-g>')
    map! <expr> <C-@><C-g>7 Prefixcountmap (v:count * 10 + 7, '<Esc>', '<C-@><C-g>')
    map! <expr> <C-@><C-g>8 Prefixcountmap (v:count * 10 + 8, '<Esc>', '<C-@><C-g>')
    map! <expr> <C-@><C-g>9 Prefixcountmap (v:count * 10 + 9, '<Esc>', '<C-@><C-g>')
    tmap <expr> <C-@><C-g>1 Prefixcountmap (v:count * 10 + 1, '<C-@>N', '<C-@><C-g>')
    tmap <expr> <C-@><C-g>2 Prefixcountmap (v:count * 10 + 2, '<C-@>N', '<C-@><C-g>')
    tmap <expr> <C-@><C-g>3 Prefixcountmap (v:count * 10 + 3, '<C-@>N', '<C-@><C-g>')
    tmap <expr> <C-@><C-g>4 Prefixcountmap (v:count * 10 + 4, '<C-@>N', '<C-@><C-g>')
    tmap <expr> <C-@><C-g>5 Prefixcountmap (v:count * 10 + 5, '<C-@>N', '<C-@><C-g>')
    tmap <expr> <C-@><C-g>6 Prefixcountmap (v:count * 10 + 6, '<C-@>N', '<C-@><C-g>')
    tmap <expr> <C-@><C-g>7 Prefixcountmap (v:count * 10 + 7, '<C-@>N', '<C-@><C-g>')
    tmap <expr> <C-@><C-g>8 Prefixcountmap (v:count * 10 + 8, '<C-@>N', '<C-@><C-g>')
    tmap <expr> <C-@><C-g>9 Prefixcountmap (v:count * 10 + 9, '<C-@>N', '<C-@><C-g>')
    
    function! Prefixcountmap(initcount, prefix, countprefix)
     let termcount = a:initcount
     while 1
      try
       let char = getchar()
      catch /^Vim:Interrupt$/
       return ""
       endtry
    
      if type(char) == 0
       let char = nr2char(char)
       endif
    
      if char == '0'
       let termcount = termcount * 10
      elseif char == '1'
       let termcount = termcount * 10 + 1
      elseif char == '2'
       let termcount = termcount * 10 + 2
      elseif char == '3'
       let termcount = termcount * 10 + 3
      elseif char == '4'
       let termcount = termcount * 10 + 4
      elseif char == '5'
       let termcount = termcount * 10 + 5
      elseif char == '6'
       let termcount = termcount * 10 + 6
      elseif char == '7'
       let termcount = termcount * 10 + 7
      elseif char == '8'
       let termcount = termcount * 10 + 8
      elseif char == '9'
       let termcount = termcount * 10 + 9
      else
       return a:prefix .. termcount .. a:countprefix .. char
       endif
    
      endwhile
     endfunction
qazxcvbnm
·ano passado·discuss
Some other things I do:

Invoke terminals on directories (instead of netrw). So, I can e.g. sp. to split to a new terminal.

  function! Isdir(dir) abort
   return !empty(a:dir) && (isdirectory(a:dir) ||
    \ (!empty($SYSTEMDRIVE) && isdirectory('/'..tolower($SYSTEMDRIVE[0])..a:dir)))
   endfunction
  
  augroup terminal-explorer
   au!
   au VimEnter * sil! au! FileExplorer *
   au VimEnter * sil! au! Network *
   au VimEnter * sil! au! AuNetrwEvent *
   " au FileType netrw cd % | bw | exe 'terminal ++curwin'
   au BufEnter * if &filetype != 'netrw' && Isdir(expand('%')) | lcd % | exe bufnr("%") ..'bufdo terminal ++curwin' | endif
   augroup end
Make <C-@>m close windows instead:

    noremap <C-@>m <C-w>c
    noremap! <C-@>m <Esc><C-w>c
    tnoremap <C-@>m <C-@>c
Make <C-@>p find the next window if there is no previous window:

    noremap <expr> <silent> <C-@>p ':<C-u>wincmd p <Bar> if win_getid () == ' .. win_getid () .. ' <Bar> wincmd w <Bar> endif <CR>'
    noremap! <expr> <silent> <C-@>p '<Esc>:<C-u>wincmd p <Bar> if win_getid () == ' .. win_getid () .. ' <Bar> wincmd w <Bar> endif <CR>'
    tnoremap <expr> <silent> <C-@>p '<C-@>:<C-u>wincmd p <Bar> if win_getid () == ' .. win_getid () .. ' <Bar> wincmd w <Bar> endif <CR>'
Use <C-@>~. to detach the GNU screen that my vim is running in (I put my vim in a screen with `unbindall` i.e. I use screen merely for keeping my vim alive) (<C-@>~. is in analogy to the SSH quit keybinding <CR>~.).

    noremap <expr> <silent> <C-@>~. ':<C-u>silent !screen -X detach<CR>'
    noremap! <expr> <silent> <C-@>~. '<C-@>:<C-u>silent !screen -X detach<CR>'
    tnoremap <expr> <silent> <C-@>~. '<C-@>:<C-u>silent !screen -X detach<CR>'
With gf and gF, opening files just from a terminal grep is practically more convenient than vim's :grep. For gf in a new tab:

    map <silent> <C-@><C-f> :<C-u>tab split<CR>gf
With terminal multiplexing in vim, you start getting a lot of buffers. You can consider getting a custom tabline. Other tab management features become more important too. You might expect [count]gt to behave just like gt for [count] times:

    nnoremap <expr> gt '@_' .. ((v:count1 + (tabpagenr () - 1)) % (tabpagenr('$') ) + 1) .. 'gt'
For ease of moving to the last tab:

    nnoremap <expr> g<C-t> '@_' .. (((v:count == 0) ? tabpagenr ('$') : v:count)) .. 'gt'
To consistently access the gt family of bindings regardless of mode:

    map <C-@>gt gt
    map <C-@>gT gT
    map <C-@>g<C-t> g<C-t>
    map! <C-@>gt <Esc>gt
    map! <C-@>gT <Esc>gT
    map! <C-@>g<C-t> <Esc>g<C-t>
    tmap <C-@>gt <C-@>Ngt
    tmap <C-@>gT <C-@>NgT
    tmap <C-@>g<C-t> <C-@>Ng<C-t>
When you use <C-w>T a lot to move your windows in to new tabs, you might sometimes want to move them to the previous tab instead of the next one:

    nnoremap <silent> <C-@><C-t> <C-w>T
    nnoremap <silent> <C-@>T <C-w>T:<C-u>tabm -1<CR>
To access these two in any mode consistently:

    map! <C-@><C-t> <Esc><C-@><C-t>
    map! <C-@>T <Esc><C-@>T
    tmap <C-@><C-t> <C-@>N<C-@><C-t>
    tmap <C-@>T <C-@>N<C-@>T
Analogously to gt and gT, sometimes you may want to move your tabs around, or split them:

    function! SSStabmadjust(tabmnum)
     if a:tabmnum < tabpagenr ()
      return a:tabmnum - 1
     else
      return a:tabmnum
      endif
     endfunction

    noremap <silent> <C-@><C-g>s :<C-u>tab split<CR>
    noremap <expr> <silent> <C-@><C-g>t '@_:<C-u>' .. SSStabmadjust ((v:count1 + (tabpagenr () - 1 )) % (tabpagenr('$') ) + 1) .. 'tabm<CR>'
    noremap <expr> <silent> <C-@><C-g>T '@_:<C-u>' .. SSStabmadjust (((- v:count1 + (tabpagenr () - 1 )) % (tabpagenr('$') ) + tabpagenr('$') ) % (tabpagenr('$') ) + 1) .. 'tabm<CR>'
    noremap <expr> <silent> <C-@><C-g><C-t> ':<C-u>' .. ((v:count == 0) ? "" : SSStabmadjust ((v:count % (tabpagenr ('$') )) )) .. 'tabm<CR>'
    map! <C-@><C-g>s <Esc><C-@><C-g>s
    map! <C-@><C-g>t <Esc><C-@><C-g>t
    map! <C-@><C-g>T <Esc><C-@><C-g>T
    map! <C-@><C-g><C-t> <Esc><C-@><C-g><C-t>
    tmap <C-@><C-g>s <C-@>N<C-@><C-g>s
    tmap <C-@><C-g>t <C-@>N<C-@><C-g>t
    tmap <C-@><C-g>T <C-@>N<C-@><C-g>T
    tmap <C-@><C-g><C-t> <C-@>N<C-@><C-g><C-t>
qazxcvbnm
·ano passado·discuss
vimrc for 4)

    vnoremap <C-@>s <C-w>sgv
    vnoremap <C-@>v <C-w>vgv

    nnoremap <expr> <C-@>w '@_' .. ((v:count1 + (winnr() - 1)) % (winnr('$')) + 1) .. '<C-w>w'
    nnoremap <expr> <C-@>W '@_' .. (((- v:count1 + (winnr() - 1)) % (winnr('$')) + winnr('$')) % (winnr('$')) + 1) .. '<C-w>w'
    nnoremap <expr> <C-@>t '@_' .. ((v:count1 - 1) % (winnr('$')) + 1) .. '<C-w>w'
    nnoremap <expr> <C-@>b '@_' .. (((- v:count1) % (winnr('$')) + winnr('$')) % (winnr('$')) + 1) .. '<C-w>w'
    inoremap <C-@><C-@> <C-@>
    map! <C-@>w <Esc><C-@>w
    map! <C-@>W <Esc><C-@>W
    map! <C-@>t <Esc><C-@>t
    map! <C-@>b <Esc><C-@>b
    tmap <C-@>w <C-@>N<C-@>w
    tmap <C-@>W <C-@>N<C-@>W
    tmap <C-@>t <C-@>N<C-@>t
    tmap <C-@>b <C-@>N<C-@>b
qazxcvbnm
·ano passado·discuss
(equivalently, if you use screen; the key point is the \eP and the \e\\ between which the real xterm escape codes go, or else screen will eat your escape codes which will never see the light of day)

    augroup term_normal
     au!      
     autocmd WinNew * let w:winnew = 1
     autocmd CmdlineEnter * let w:outcmd = 0
     autocmd CmdlineLeave * let w:outcmd = 1
     autocmd WinEnter * if exists ('w:winnew') | unlet w:winnew | if (mode() == 't') | call Termcursor () | endif | elseif get(w:, 'outcmd', 1) && (mode() == 't') | call feedkeys("\<C-@>N", "") | endif
     autocmd WinLeave * if (mode() == 't') && (! exists('w:tu')) | call feedkeys("\<C-@>N", 'x') | call Normalcursor () | elseif (mode(1) == 'nt') && (exists('w:tu')) | call feedkeys("i", 'ix') | endif
    
     tmap <expr> <C-@><C-@> ((mode() == 't') && get(w:, 'outcmd', 1)) ? '<C-@>N' : '<C-@><C-@>'
     augroup end
    
    let &t_SI = "\eP\e[6 q\e]12;#FF00DF\<C-g>\e\\"
    let &t_EI = "\eP\e[2 q\e]12;#FF00DF\<C-g>\e\\"
    let &t_ti = "\eP\e[4 q\e]12;#FF00DF\<C-g>\e\\"
    let &t_te = "\eP\e[2 q\e]12;#FF00DF\<C-g>\e\\"
    let &t_Us = "\eP\e[4:2m\e\\"
    let &t_ds = "\eP\e[4:4m\e\\"
    let &t_Ds = "\eP\e[58:5:3m\e[4:5m\e\\"
    
    function! Normalcursor ()
     let &t_ve ="\eP\e[2 q\e]12;#FF00DF\<C-g>\e\\" 
     let &t_vi ="\eP\e[2 q\e]12;#FF00DF\<C-g>\e\\"
     endfunction
    function! Echonormalcursor ()
     call echoraw("\eP\e[2 q\e]12;#FF00DF\<C-g>\e\\")
     endfunction
    function! Termcursor ()
     let &t_ve ="\eP\e[4 q\e]12;#FF00DF\<C-g>\e\\"
     let &t_vi ="\eP\e[4 q\e]12;#FF00DF\<C-g>\e\\"
     endfunction
    function! Echotermcursor ()
     call echoraw("\eP\e[2 q\e]12;#FF00DF\<C-g>\e\\")
     endfunction
    
    augroup termcursor
     au!
     autocmd ModeChanged *:n* let &t_ve ="\eP\e[2 q\e]12;#FF00DF\<C-g>\e\\"
     autocmd ModeChanged *:n* let &t_vi ="\eP\e[2 q\e]12;#FF00DF\<C-g>\e\\"
     autocmd ModeChanged i:* if &t_ve == "" | let &t_ve ="\eP\e[2 q\e]12;#FF00DF\<C-g>\e\\" | endif
     autocmd ModeChanged i:* if &t_vi == "" | let &t_vi ="\eP\e[2 q\e]12;#FF00DF\<C-g>\e\\" | endif
     autocmd ModeChanged *:i* let &t_ve =""
     autocmd ModeChanged *:i* let &t_vi =""
     autocmd ModeChanged *:t call echoraw("\eP\e[4 q\e]12;#FF00DF\<C-g>\e\\")
     autocmd ModeChanged *:t let &t_ve ="\eP\e[4 q\e]12;#FF00DF\<C-g>\e\\"
     autocmd ModeChanged *:t let &t_vi ="\eP\e[4 q\e]12;#FF00DF\<C-g>\e\\"
     autocmd ModeChanged t:* call echoraw("\eP\e[2 q\e]12;#FF00DF\<C-g>\e\\")
     autocmd ModeChanged t:* if (mode(1) != 'ct') | let &t_ve ="\eP\e[2 q\e]12;#FF00DF\<C-g>\e\\" | endif
     autocmd ModeChanged t:* if (mode(1) != 'ct') | let &t_vi ="\eP\e[2 q\e]12;#FF00DF\<C-g>\e\\" | endif
     
     " TODO -- doesnt restore from redraw?
     let g:cmdlinedepth = 0
     autocmd CmdlineEnter * let g:cmdlinedepth = g:cmdlinedepth + 1 | let &t_ve = "\eP\e[4 q\e]12;#FF00DF\<C-g>\e\\" | let &t_vi = "\eP\e[4 q\e]12;#FF00DF\<C-g>\e\\"
     autocmd CmdlineLeave * let g:cmdlinedepth = g:cmdlinedepth - 1 | if g:cmdlinedepth == 0 | if (mode(1) == 'ct') | call Termcursor () | else | call Normalcursor () | endif | endif
     autocmd CmdwinEnter * let &t_ve ="\eP\e[2 q\e]12;#FF00DF\<C-g>\e\\" | let &t_vi ="\eP\e[2 q\e]12;#FF00DF\<C-g>\e\\"
     autocmd CmdwinLeave * let &t_ve = "\eP\e[4 q\e]12;#FF00DF\<C-g>\e\\" | let &t_vi = "\eP\e[4 q\e]12;#FF00DF\<C-g>\e\\"
    
     " autocmd WinEnter * call echoraw("\eP\e[2 q\e]12;#FF00DF\<C-g>\e\\")
     augroup end
qazxcvbnm
·ano passado·discuss
For me, some of the things that's really important for a terminal multiplexer include:

1) Keybindings having no conflicts with other terminal applications. For that, vim's default window-management key of <C-w> is unfortunate, as it is very important for delete words in bash and readline. I remap that to <C-@> (CTRL-Space) instead, which is basically used by no terminal program that I am aware of. The other key binding that trips me up are the default vim keybindings to kill the terminal (<C-w><C-c>). If I am midway attempting a window action, but realise something is taking too long and want to stop the job, the keybinding kills my whole shell. If I really want to kill my terminal, I can always issue ZQ or :q! in normal mode.

2) Change my cursor shapes based on which mode I'm in (normal, insert, or terminal/command), which helps me easily tell the mode.

3) Improve the default keybinding for going from terminal back to terminal normal mode. I find the default keybindings <C-\><C-n> and <C-w>N too difficult to type because I need to use this binding very much.

4) Be able to move between windows with the same, consistent set of keybindings no matter which mode I'm in (e.g. not having to go back to normal mode first, from insert or terminal mode). In the same vein, when I land on a buffer I always expect to be in normal mode, so I can start moving around immediately and yank stuff without remembering whether I'm in a terminal or a non-terminal buffer. When I need to manipulate the terminal program I can always `i` or `a`.

I have quite a few other customisations to my vim terminal, but I think these are the most essential ones.

vimrc for 1)

    set termwinkey=<C-@>
    noremap <C-@> <C-w>
    noremap <C-@><CR> <C-w><CR>
    noremap! <C-@> <Esc><C-w>

    noremap <C-@>c <Nop>
    noremap <C-@><C-c> <Nop>
    noremap <C-@><C-q> <Nop>
    noremap! <C-@>c <Nop>
    noremap! <C-@><C-c> <Nop>
    noremap! <C-@><C-q> <Nop>
    tnoremap <C-@>c <Nop>
    tnoremap <C-@><C-c> <Nop>
    tnoremap <C-@><C-q> <Nop>
    noremap <C-@>q <Nop>
    noremap! <C-@>q <Nop>
    tnoremap <C-@>q <Nop>
vimrc for 2) and 3)

    augroup term_normal
     au!      
     autocmd WinNew * let w:winnew = 1
     autocmd CmdlineEnter * let w:outcmd = 0
     autocmd CmdlineLeave * let w:outcmd = 1
     autocmd WinEnter * if exists ('w:winnew') | unlet w:winnew | if (mode() == 't') | call Termcursor () | endif | elseif get(w:, 'outcmd', 1) && (mode() == 't') | call feedkeys("\<C-@>N", "") | endif
     autocmd WinLeave * if (mode() == 't') && (! exists('w:tu')) | call feedkeys("\<C-@>N", 'x') | call Normalcursor () | elseif (mode(1) == 'nt') && (exists('w:tu')) | call feedkeys("i", 'ix') | endif

     tmap <expr> <C-@><C-@> ((mode() == 't') && get(w:, 'outcmd', 1)) ? '<C-@>N' : '<C-@><C-@>'
     augroup end
    
    let &t_SI = "\e[6 q\e]12;#FF00DF\<C-g>"
    let &t_EI = "\e[2 q\e]12;#FF00DF\<C-g>"
    let &t_ti = "\e[4 q\e]12;#FF00DF\<C-g>"
    let &t_te = "\e[2 q\e]12;#FF00DF\<C-g>"
    let &t_Us = "\e[4:2m"
    let &t_ds = "\e[4:4m"
    let &t_Ds = "\e[58:5:4m\e[4:5m"
    
    function! Normalcursor ()
     let &t_ve ="\e[2 q\e]12;#FF00DF\<C-g>" 
     let &t_vi ="\e[2 q\e]12;#FF00DF\<C-g>"
     endfunction
    function! Echonormalcursor ()
     call echoraw("\e[2 q\e]12;#FF00DF\<C-g>")
     endfunction
    function! Termcursor ()
     let &t_ve ="\e[4 q\e]12;#FF00DF\<C-g>"
     let &t_vi ="\e[4 q\e]12;#FF00DF\<C-g>"
     endfunction
    function! Echotermcursor ()
     call echoraw("\e[4 q\e]12;#FF00DF\<C-g>")
     endfunction
    
    augroup termcursor
     au!
     autocmd ModeChanged *:n* let &t_ve ="\e[2 q\e]12;#FF00DF\<C-g>"
     autocmd ModeChanged *:n* let &t_vi ="\e[2 q\e]12;#FF00DF\<C-g>"
     autocmd ModeChanged i:* if &t_ve == "" | let &t_ve ="\e[2 q\e]12;#FF00DF\<C-g>" | endif
     autocmd ModeChanged i:* if &t_vi == "" | let &t_vi ="\e[2 q\e]12;#FF00DF\<C-g>" | endif
     autocmd ModeChanged *:i* let &t_ve =""
     autocmd ModeChanged *:i* let &t_vi =""
     autocmd ModeChanged *:t call echoraw("\e[4 q\e]12;#FF00DF\<C-g>")
     autocmd ModeChanged *:t let &t_ve ="\e[4 q\e]12;#FF00DF\<C-g>"
     autocmd ModeChanged *:t let &t_vi ="\e[4 q\e]12;#FF00DF\<C-g>"
     autocmd ModeChanged t:* call echoraw("\e[2 q\e]12;#FF00DF\<C-g>")
     autocmd ModeChanged t:* if (mode(1) != 'ct') | let &t_ve ="\e[2 q\e]12;#FF00DF\<C-g>" | endif
     autocmd ModeChanged t:* if (mode(1) != 'ct') | let &t_vi ="\e[2 q\e]12;#FF00DF\<C-g>" | endif
    
     let g:cmdlinedepth = 0
     autocmd CmdlineEnter * let g:cmdlinedepth = g:cmdlinedepth + 1 | let &t_ve = "\e[4 q\e]12;#FF00DF\<C-g>" | let &t_vi = "\e[4 q\e]12;#FF00DF\<C-g>"
     autocmd CmdlineLeave * let g:cmdlinedepth = g:cmdlinedepth - 1 | if g:cmdlinedepth == 0 | if (mode(1) == 'ct') | call Termcursor () | else | call Normalcursor () | endif | endif
     autocmd CmdwinEnter * let &t_ve ="\e[2 q\e]12;#FF00DF\<C-g>" | let &t_vi ="\e[2 q\e]12;#FF00DF\<C-g>"
     autocmd CmdwinLeave * let &t_ve = "\e[4 q\e]12;#FF00DF\<C-g>" | let &t_vi = "\e[4 q\e]12;#FF00DF\<C-g>"
     
     " autocmd WinEnter * call echoraw("\e[2 q\e]12;#FF00DF\<C-g>")
qazxcvbnm
·ano passado·discuss
Just for the other side of the picture, I live in vim and use it as my terminal multiplexer. Vim’s my shell. I have thousands of buffers in vim and practically never leave it. I’ve used terminal multiplexers for years before I switched to vim in that capacity and never looked back. The integration it’s allowed between all my buffers and commands and shells is difficult to match in my opinion.
qazxcvbnm
·ano passado·discuss
By the way, is it Shopify’s open source policy to ignore outside PRs, or are they simply understaffed? My PR which addresses a major issue in one of Shopify’s big React Native libraries has received zero acknowledgement from Shopify for almost a year.
qazxcvbnm
·há 2 anos·discuss
Yes, I might have misworded my question. My question is in relation to this paragraph on page 12:

"Note that the SQL ORDER BY directive can be modelled as a non-linear aggregate function that emits a list. However, such an implementation is not efficiently incrementalizable in DBSP. We leave the efficient handling of ORDER BY to future work."

My understanding is that Feldera does indeed support ORDER BY, which I imagine it does incrementally, thus my question.

The statement in the paper that ordering is not efficiently incrementalisable seems to makes sense to me. It is clear that even though Z-sets are not naively able to represent diffs of ordered relations (since Z-sets are unordered), ordering can be modelled as an aggregate that first builds up the first row, then the second row, and so on. Even as formulated this way however, I fail to see how the entire "incrementalised" computation would still be practically incremental, in the sense that the size of the output diff (Z-set) is small as long as the diff of the input is small.

For example, consider the query `select x from y order by x asc`, and the following values respectively occur in the stream of x: 5, 4, 3, 2, 1. Now, consider the incremental diff for the last value of 1. If presumably one models order by a list aggregation, then the Z-set for the entire computation seems to be

    - [ 2, 3, 4, 5 ]
    + [ 1, 2, 3, 4, 5 ]
which grows with the size of the output set rather than the size of the input diff. If presumably one models order by e.g. adding an order column, the diff would be

    - 2 (index: 0)
    - 3 (index: 1)
    - 4 (index: 2)
    - 5 (index: 3)
    + 1 (index: 0)
    + 2 (index: 1)
    + 3 (index: 2)
    + 4 (index: 3)
    + 5 (index: 4)
which once again varies with the size of the output set.
qazxcvbnm
·há 2 anos·discuss
Hi, I’ve read the DBSP paper and it’s a really well-thought out framework; all the magic seemed so simple with the way the paper laid things out. However, the paper dealt with abelian Z-sets only, and mentioned that in your implementation, you also handle the non-abelian aspect of ordering. I was wondering if you guys have published about how did you that?