Я копирую материал с буферов вывода в код C++, я продолжаю работать в энергии. Часто этот вывод застревает в строки. И было бы хорошо смочь выйти из всех управляющих символов автоматически вместо возвращения и руки, редактируя вставляемый фрагмент.
Как пример я мог бы скопировать что-то вроде этого:
error in file "foo.dat"
И должен поместить его во что-то вроде этого
std::string expected_error = "error in file \"foo.dat\""
Я думаю, что могло бы быть возможно применить функцию замены к органу по последней вставке с помощью запуска и меток конца последней вставки, но я не уверен, как заставить его полететь.
ОБНОВЛЕНИЕ:
Joey Mazzarelli предложил использовать
`[v`]h:%s/\%V"/\\"/g
после вставки.
Так как никакой explaination не был дан, для какого это шло и я первоначально нашел это немного кратким, но трудно объяснить в комментариях, я думал, что поместил explaination того, что я думаю, что это делает здесь:
`[ : Move to start of last paste
v : Start visual mode
`] : Move to end of last paste
h : adjust cursor one position left
:% : apply on the lines of the selection
s/ : replace
\%V : within the visual area
" : "
/ : with
\\" : \"
/g : all occurrences
Это походит на хороший подход, но только обрабатывает один символ, ", я хотел бы, чтобы он обработал новые строки, вкладки и другие вещи, которые, как могли бы ожидать, упадут в тексте. (Вероятно, не общий unicode, хотя), я понимаю, что это не могло быть ясно в проблемном определении.
Вот пара функций vimscript это должно делать то, что вы хотите.
EscapeText ()
преобразует произвольный текст в эквивалент с экранированием на языке C. Он преобразует новую строку в \ n
, табуляцию в \ t
, Control + G в \ a
и т. Д. И генерирует восьмеричные escape-символы (например, \ o032
) для специальных символов, у которых нет понятного имени.
PasteEscapedRegister ()
экранирует содержимое регистра с именем v: register
, затем вставляет его в текущий буфер. (Регистр восстанавливается, когда функция возвращается, поэтому функцию можно вызывать несколько раз, не экранируя содержимое регистра несколько раз.)
Также включены несколько сопоставлений клавиш, чтобы упростить PasteEscapedRegister ()
использовать в интерактивном режиме.
вставляет экранированное содержимое регистра перед позицией курсора, а
вставляет после. Оба могут иметь префикс со спецификацией регистра, например "a \ P
, чтобы вставить экранированное содержимое регистра a.
Вот код:
function! EscapeText(text)
let l:escaped_text = a:text
" Map characters to named C backslash escapes. Normally, single-quoted
" strings don't require double-backslashing, but these are necessary
" to make the substitute() call below work properly.
"
let l:charmap = {
\ '"' : '\\"',
\ "'" : '\\''',
\ "\n" : '\\n',
\ "\r" : '\\r',
\ "\b" : '\\b',
\ "\t" : '\\t',
\ "\x07" : '\\a',
\ "\x0B" : '\\v',
\ "\f" : '\\f',
\ }
" Escape any existing backslashes in the text first, before
" generating new ones. (Vim dictionaries iterate in arbitrary order,
" so this step can't be combined with the items() loop below.)
"
let l:escaped_text = substitute(l:escaped_text, "\\", '\\\', 'g')
" Replace actual returns, newlines, tabs, etc., with their escaped
" representations.
"
for [original, escaped] in items(charmap)
let l:escaped_text = substitute(l:escaped_text, original, escaped, 'g')
endfor
" Replace any other character that isn't a letter, number,
" punctuation, or space with a 3-digit octal escape sequence. (Octal
" is used instead of hex, since octal escapes terminate after 3
" digits. C allows hex escapes of any length, so it's possible for
" them to run up against subsequent characters that might be valid
" hex digits.)
"
let l:escaped_text = substitute(l:escaped_text,
\ '\([^[:alnum:][:punct:] ]\)',
\ '\="\\o" . printf("%03o",char2nr(submatch(1)))',
\ 'g')
return l:escaped_text
endfunction
function! PasteEscapedRegister(where)
" Remember current register name, contents, and type,
" so they can be restored once we're done.
"
let l:save_reg_name = v:register
let l:save_reg_contents = getreg(l:save_reg_name, 1)
let l:save_reg_type = getregtype(l:save_reg_name)
echo "register: [" . l:save_reg_name . "] type: [" . l:save_reg_type . "]"
" Replace the contents of the register with the escaped text, and set the
" type to characterwise (so pasting into an existing double-quoted string,
" for example, will work as expected).
"
call setreg(l:save_reg_name, EscapeText(getreg(l:save_reg_name)), "c")
" Build the appropriate normal-mode paste command.
"
let l:cmd = 'normal "' . l:save_reg_name . (a:where == "before" ? "P" : "p")
" Insert the escaped register contents.
"
exec l:cmd
" Restore the register to its original value and type.
"
call setreg(l:save_reg_name, l:save_reg_contents, l:save_reg_type)
endfunction
" Define keymaps to paste escaped text before or after the cursor.
"
nmap <Leader>P :call PasteEscapedRegister("before")<cr>
nmap <Leader>p :call PasteEscapedRegister("after")<cr>
По крайней мере, это может помочь вам начать ...
После вставки в:
`[v`]h:%s/\%V"/\\"/g
Вы, очевидно, можете сопоставить это с чем-то более простым для ввода.
Хотя решение Joeys выглядит так, будто оно может быть расширяемым, чтобы покрыть все случаи, которые мне нужны, я решил поделиться своим частичным решением, используя vims python integration (Поскольку я более знаком с python, чем с vim script)
# FILE : tocstring.py
import vim
def setRegister(reg, value):
vim.command( "let @%s='%s'" % (reg, value.replace("'","''") ) )
def getRegister(reg):
return vim.eval("@%s" % reg )
def transformChar( map, c):
if c in map:
return map[c]
return c
def transformText( map, text ):
return ''.join( [ transformChar(map,c) for c in text ] )
cmap={}
cmap["\\"]="\\\\"
cmap["\n"]="\\n"
cmap["\t"]=r"\\t"
cmap['"']="\\\""
def convertToCString( inregister, outregister ):
setRegister(outregister, transformText( cmap, getRegister(inregister) ) )
Затем в моем . vimrc или другом conf-файле я могу поставить
# FILE cpp.vim
python import tocstring
# C-Escape and paste the currently yanked content
nmap <Leader>P :python tocstring.convertToCString("@","z")<CR>"zP
# C-Escape and paste the current visual selection
vmap <Leader>P "zd:python tocstring.convertToCString("z","z")<CR>"zP
Было бы неплохо, если бы я мог заставить первую функцию работать так, чтобы "a\P вставляла преобразованное содержимое регистра "a", и я предполагаю, что это можно сделать, как-то используя v:register, но это ускользает от меня.
Версия этого, которая работает так же, как решение Joeys, может быть оформлена как
nmap <Leader>P `[v`]"zd:python tocstring.convertToCString("z","z")<CR>"zP
Благодарность: Здесь используется код из Можно ли получить доступ к регистрам из функций python в vim для взаимодействия с регистрами из vims python