Skip to content

Commit

Permalink
Merge pull request #72 from kamecha/feature/message-pin
Browse files Browse the repository at this point in the history
なんかもっと良さげな実装ありそうだけど、いったんこれで†コミット†しちゃぇ~
  • Loading branch information
kamecha authored Dec 13, 2023
2 parents 4ba5aab + 7c70956 commit 632c3e2
Show file tree
Hide file tree
Showing 7 changed files with 199 additions and 2 deletions.
1 change: 1 addition & 0 deletions autoload/helper.vim
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ function! helper#define_highlight() abort
highlight! VtraQScreenName ctermfg=lightmagenta guifg=lightmagenta cterm=bold
highlight! link VtraQQuote Comment
highlight! link VtraQMessage Keyword
highlight! link VtraQPin Keyword
endfunction
83 changes: 82 additions & 1 deletion autoload/traqvim.vim
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ endfunction

function! traqvim#draw_timeline(bufNum) abort
call setbufvar(a:bufNum, "&modifiable", 1)
call sign_unplace("VtraQ", #{ buffer: a:bufNum })
let index = 0
let start = 1
let winnr = bufwinid(a:bufNum)
Expand All @@ -27,13 +28,48 @@ function! traqvim#draw_timeline(bufNum) abort
" 一度に全部描画するから、positionをここで設定する
let message.position = #{ index: index, start: start, end: end }
call setbufline(a:bufNum, start, body)
if message->get('pinned')
call sign_place(0, "VtraQ", "pin", a:bufNum, #{ lnum: start, priority: 10 })
for i in range(start + 1, end - 1)
call sign_place(0, "VtraQ", "pin_long", a:bufNum, #{ lnum: i, priority: 10 })
endfor
endif
let start = end + 1
let index = index + 1
endfor
call deletebufline(a:bufNum, start, '$')
call setbufvar(a:bufNum, "&modifiable", 0)
endfunction

function traqvim#draw_message_pin(bufNum, message) abort
call setbufvar(a:bufNum, "&modifiable", 1)
let start = a:message.position["start"]
let end = a:message.position["end"]
if a:message->get('pinned')
call sign_place(0, "VtraQ", "pin", a:bufNum, #{ lnum: start, priority: 10 })
for i in range(start + 1, end - 1)
call sign_place(0, "VtraQ", "pin_long", a:bufNum, #{ lnum: i, priority: 10 })
endfor
else
" unplaceはbufferとidしか指定できない
let pin_signs = sign_getplaced(a:bufNum, #{ group: "VtraQ", lnum: start })
\ ->filter({ _, v -> v->get('bufnr') == a:bufNum })
\ ->get(0)
call sign_unplace(
\"VtraQ",
\#{ buffer: a:bufNum, id: pin_signs->get('signs')->get(0)->get('id') })
for i in range(start + 1, end - 1)
let pin_long_signs = sign_getplaced(a:bufNum, #{ group: "VtraQ", lnum: i })
\ ->filter({ _, v -> v->get('bufnr') == a:bufNum })
\ ->get(0)
call sign_unplace(
\"VtraQ",
\#{ buffer: a:bufNum, id: pin_long_signs->get('signs')->get(0)->get('id') })
endfor
endif
call setbufvar(a:bufNum, "&modifiable", 0)
endfunction

function! traqvim#draw_forward_messages(bufNum, messages) abort
call setbufvar(a:bufNum, "&modifiable", 1)
" startをバッファの最下値にする
Expand All @@ -44,6 +80,12 @@ function! traqvim#draw_forward_messages(bufNum, messages) abort
let body = traqvim#make_message_body(message, width)
let end = start + len(body) - 1
call appendbufline(a:bufNum, start - 1, body)
if message->get('pinned')
call sign_place(0, "VtraQ", "pin", a:bufNum, #{ lnum: start, priority: 10 })
for i in range(start + 1, end - 1)
call sign_place(0, "VtraQ", "pin_long", a:bufNum, #{ lnum: i, priority: 10 })
endfor
endif
let start = end + 1
endfor
" この関数を呼ばれる前に追加分が既にバッファ変数に登録されてる
Expand All @@ -62,6 +104,12 @@ function! traqvim#draw_back_messages(bufNum, messages) abort
let body = traqvim#make_message_body(message, width)
let end = start + len(body) - 1
call appendbufline(a:bufNum, start - 1, body)
if message->get('pinned')
call sign_place(0, "VtraQ", "pin", a:bufNum, #{ lnum: start, priority: 10 })
for i in range(start + 1, end - 1)
call sign_place(0, "VtraQ", "pin_long", a:bufNum, #{ lnum: i, priority: 10 })
endfor
endif
let start = end + 1
endfor
" 既存のメッセージのpositionを更新する
Expand All @@ -74,6 +122,12 @@ function traqvim#draw_delete_message(bufNum, message) abort
call setbufvar(a:bufNum, "&modifiable", 1)
let start = a:message.position["start"]
let end = a:message.position["end"]
if a:message->get('pinned')
call sign_unplace("VtraQ", #{ buffer: a:bufNum, lnum: start })
for i in range(start + 1, end - 1)
call sign_unplace("VtraQ", #{ buffer: a:bufNum, lnum: i })
endfor
endif
call deletebufline(a:bufNum, start, end)
" 既存のメッセージのpositionを更新する
" この関数を呼ばれる前に削除分が既にバッファ変数から削除されてる
Expand Down Expand Up @@ -102,6 +156,12 @@ function traqvim#draw_insert_message(bufNum, message) abort
let body = traqvim#make_message_body(a:message, width)
let end = start + len(body) - 1
call appendbufline(a:bufNum, start - 1, body)
if a:message->get('pinned')
call sign_place(0, "VtraQ", "pin", a:bufNum, #{ lnum: start, priority: 10 })
for i in range(start + 1, end - 1)
call sign_place(0, "VtraQ", "pin_long", a:bufNum, #{ lnum: i, priority: 10 })
endfor
endif
" 既存のメッセージのpositionを更新する
call map(timeline, function("traqvim#update_message_position", [timeline]))
call setbufvar(a:bufNum, "&modifiable", 0)
Expand Down Expand Up @@ -158,7 +218,7 @@ function! traqvim#make_message_body(message, width) abort
endfor
endif
endif
let footer = [ "", repeat("", a:width) ]
let footer = [ "", repeat("", a:width - 2) ] " 2はsigncolumnの分
let messageBody = header + rows + quote + footer
return messageBody
endfunction
Expand Down Expand Up @@ -255,6 +315,27 @@ function traqvim#deleteMessage(t) abort
call denops#request('traqvim', 'messageDelete', [bufnr(), messageStart])
endfunction

function traqvim#registerTogglePin() abort
let &opfunc = function('traqvim#togglePin')
return 'g@'
endfunction

function traqvim#togglePin(t) abort
if a:t != 'line'
return
endif
let messageStart = traqvim#get_message_buf(line("'["), bufnr('%'))
let messageEnd = traqvim#get_message_buf(line("']"), bufnr('%'))
if messageStart->get('id') != messageEnd->get('id')
return
endif
if messageStart->get('pinned')
call denops#request('traqvim', 'removePin', [bufnr(), messageStart])
else
call denops#request('traqvim', 'createPin', [bufnr(), messageStart])
endif
endfunction

function traqvim#message_motion() abort
let position = traqvim#get_message()->get('position')
call cursor(position->get('start'), 1)
Expand Down
62 changes: 62 additions & 0 deletions denops/traqvim/action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ import {
activity,
channelMessageOptions,
channelTimeline,
createPin,
deleteMessage,
editMessage,
removePin,
} from "./model.ts";

export const actionOpenChannel = async (
Expand Down Expand Up @@ -184,3 +186,63 @@ export const actionYankMessageMarkdown = async (
await fn.setreg(denops, '"', message.content);
await helper.echo(denops, "Yanked message markdown");
};

export const actionCreatePin = async (
denops: Denops,
message: Message,
bufNum: number,
): Promise<void> => {
try {
await createPin(message.id);
} catch (e) {
console.error(e);
return;
}
// 既存メッセージの取得
const timeline = await vars.buffers.get(denops, "channelTimeline");
ensureArray<Message>(timeline);
message.pinned = true;
// ピン留めしたものをセット
await vars.buffers.set(
denops,
"channelTimeline",
timeline.map((m) => {
if (m.id === message.id) {
return message;
} else {
return m;
}
}),
);
await denops.call("traqvim#draw_message_pin", bufNum, message);
};

export const actionRemovePin = async (
denops: Denops,
message: Message,
bufNum: number,
): Promise<void> => {
try {
await removePin(message.id);
} catch (e) {
console.error(e);
return;
}
// 既存メッセージの取得
const timeline = await vars.buffers.get(denops, "channelTimeline");
ensureArray<Message>(timeline);
message.pinned = false;
// ピン留め解除したものをセット
await vars.buffers.set(
denops,
"channelTimeline",
timeline.map((m) => {
if (m.id === message.id) {
return message;
} else {
return m;
}
}),
);
await denops.call("traqvim#draw_message_pin", bufNum, message);
};
18 changes: 18 additions & 0 deletions denops/traqvim/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@ import {
} from "./deps.ts";
import {
actionBackChannelMessage,
actionCreatePin,
actionDeleteMessage,
actionEditMessage,
actionForwardChannelMessage,
actionOpenActivity,
actionOpenChannel,
actionRemovePin,
actionYankMessageLink,
actionYankMessageMarkdown,
} from "./action.ts";
Expand Down Expand Up @@ -337,5 +339,21 @@ export async function main(denops: Denops) {
await denops.cmd(":bdelete");
return;
},
async createPin(
bufNum: unknown,
message: unknown,
): Promise<unknown> {
ensureNumber(bufNum);
await actionCreatePin(denops, message as Message, bufNum);
return;
},
async removePin(
bufNum: unknown,
message: unknown,
): Promise<unknown> {
ensureNumber(bufNum);
await actionRemovePin(denops, message as Message, bufNum);
return;
},
};
}
20 changes: 20 additions & 0 deletions denops/traqvim/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -291,3 +291,23 @@ export const editMessage = async (
console.error(e);
}
};

export const createPin = async (
messageId: string,
): Promise<void> => {
try {
await api.api.createPin(messageId);
} catch (e) {
console.error(e);
}
};

export const removePin = async (
messageId: string,
): Promise<void> => {
try {
await api.api.removePin(messageId);
} catch (e) {
console.error(e);
}
};
13 changes: 12 additions & 1 deletion ftplugin/traqvim.vim
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@

setlocal noswapfile
setlocal signcolumn=no
setlocal signcolumn=yes
setlocal nolist

" TODO: nerd font導入してるかの確認とかしたいな
" call sign_define("pin", #{ text: "📌"})
call sign_define("pin", #{ text: "󰐃", texthl: "VtraQPin"}) "f0403 ← nerd font導入後、これに対応してるらしい
call sign_define("pin_long", #{ text: "" , texthl: "VtraQPin"})

nnoremap <buffer><silent> <Plug>(traqvim-next)
\ <Cmd>call traqvim#message_next()<CR>
nnoremap <buffer><silent> <Plug>(traqvim-prev)
Expand All @@ -13,6 +19,8 @@ nnoremap <buffer><expr> <Plug>(traqvim-yank-message-markdown-operator)
\ traqvim#registerYankMessageMarkdown()
nnoremap <buffer><expr> <Plug>(traqvim-delete-message-operator)
\ traqvim#registerDeleteMessage()
nnoremap <buffer><expr> <Plug>(traqvim-toggle-pin-operator)
\ traqvim#registerTogglePin()
onoremap <silent> <Plug>(traqvim-message-motion)
\ :<C-u>call traqvim#message_motion()<CR>
Expand All @@ -29,6 +37,9 @@ nmap <buffer> <LocalLeader>Y
nmap <buffer> <LocalLeader>d
\ <Plug>(traqvim-delete-message-operator)
nmap <buffer> <LocalLeader>p
\ <Plug>(traqvim-toggle-pin-operator)
command! -buffer -nargs=0 TraqYankMessageLink
\ call denops#request('traqvim', 'yankMessageLink', [traqvim#get_message()])
command! -buffer -nargs=0 TraqYankMessageMarkdown
Expand Down
4 changes: 4 additions & 0 deletions plugin/traqvim.vim
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ command! TraqMessageDelete call denops#request('traqvim', 'messageDelete', [bufn
command! TraqMessageEdit call denops#request('traqvim', 'messageEditOpen', [bufnr(), traqvim#get_message()])
" messageの編集を適用
command! TraqMessageEditApply call denops#request('traqvim', 'messageEdit', [getbufvar(bufname("%"), "editSourceBuffer"), getbufvar(bufname("%"), "message"), getline(1, '$')])
" pinを作成
command! TraqCreatePin call denops#request('traqvim', 'createPin', [bufnr(), traqvim#get_message()])
" pinを削除
command! TraqRemovePin call denops#request('traqvim', 'removePin', [bufnr(), traqvim#get_message()])

call helper#define_highlight()

Expand Down

0 comments on commit 632c3e2

Please sign in to comment.