I need to copy part of the file (with re-search-forward) to another file under the marker. I know how to use re-search-forward, but I have problems with buffer.
Am i right with my logic?
1) open needed file with temp buffer
2) create new buffer
3) find needed lines with re-search-forward and copy them in this new
buffer
4) insert lines into opened file with insert-buffer-substring
Right now i have a function like this:
(defun my-insert-file-name (filename)
(interactive "*fInsert file name: ")
(save-excursion
(goto-char (point-min))
(when (re-search-forward "#here")
(forward-line 1)
(------something should be here-----)))
Your question is short on details, but maybe something like this?
(let (buf)
(with-temp-buffer
(setq buf (current-buffer))
(insert-file-contents "/file/to/insert")
(do-stuff-to-temp-buffer)
(with-current-buffer "buffer-to-insert-into"
(insert-buffer-substring buf))))
Related
I am writing some code where I import some files under TMX (a form of xml).
I tried various options
a) using the Open FileName For input, but this messes up the character encoding
b) opening the file and copying the data using the msoDialog, but this return an error if the file is too large (which is often the case) and this put the data in an utterly messy manner.
c) opening the file using notepad, but there are the same limitations in so far as copying the entirety of the file into Excel as the previous option.
I am not trying to use a shell function calling onto Wordpad.
My issue right now, is that I need to copy the file line by line to treat its content according to my needs (hopefully without losing the character encoding
Would someone know how to copy every single line from the file opened in WordPad and paste it post treatment (selection of the relevant elements) into Excel?
Thank you
For large files you can use this solution:
Public Sub ImportTMXtoExcel()
Call Application.FileDialog(msoFileDialogOpen).Filters.Clear
Call Application.FileDialog(msoFileDialogOpen).Filters.Add("TMX Files", "*.tmx")
Application.FileDialog(msoFileDialogOpen).Title = "Select a file to import..."
Application.FileDialog(msoFileDialogOpen).AllowMultiSelect = False
intChoice = Application.FileDialog(msoFileDialogOpen).Show
If intChoice <> 0 Then
strFileToImport = Application.FileDialog(msoFileDialogOpen).SelectedItems(1)
Else
Exit Sub
End If
intPointer = FreeFile()
Open strFileToImport For Input Access Read Lock Read As #intPointer
intCounter = 0
Do Until EOF(intPointer)
Line Input #intPointer, strLine
intCounter = intCounter + 1
Worksheets(1).Cells(intCounter + 1, 1).Value2 = strLine
Loop
Close intPointer
End Sub
For other encodings you can use ADO's Stream as described in this solution:
VB6/VBScript change file encoding to ansi
If you have large files which require ADO's Stream then you might want to consider breaking down the large files first as described in this solution:
How to split a large text file into smaller files with equal number of lines?
The following website provides a tool which mimics the Unix command split for Windows in command prompt: https://www.fourmilab.ch/splits/
I want to dynamically change the way latex-suite determines the MainFile.
The main file is usually the latex header file which includes other tex files (like chapters and so on). Using the MainFile it is possible to hit compile on some chapter-file so that latex-suite automatically compiles the header file instead.
This should be possible with g:Tex_MainFileExpression:
http://vim-latex.sourceforge.net/documentation/latex-suite/latex-master-file.html
However, the expression is not documented at all and even the example (which imo should reflect the default behavior) does not work.
let g:Tex_MainFileExpression = 'MainFile(modifier)'
function! MainFile(fmod)
if glob('*.latexmain') != ''
return fnamemodify(glob('*.latexmain'), a:fmod)
else
return ''
endif
endif
Can somebody please shortly point out to me how this is supposed to be used?
What return expression is expected? Why does the example not work?
Background: I have a latexmain file in the project root. I also have a figure subdirectory. For this subdirectory the root latex main should not be ignored, so that the current file itself is compiled.
I just ran into the problem of not knowing how to set g:Tex_MainFileExpression as well. The documentation and the example were not clear to me either. Turns out, the source code defines a function Tex_GetMainFileName, which sets the variable modifier from its arguments before executing g:Tex_MainFileExpression (see source code here). Therefore, g:Tex_MainFileExpression needs to be a function that has the argument modifier (not called differently!). The vim-latex documentation says, that modifier is a filetype-modifier, therefore your function needs to return fnamemodify(filename, modifier). So it has to look like this:
let g:Tex_MainFileExpression = 'MainFile(modifier)'
function! MainFile(fmod)
" Determine the full path to your main latex file that you want to compile.
" Store it e.g. in the variable `path`:
" let path = some/path/to/main.tex
" Apply `modifier` to your `path` variable
return fnamemodify(path, a:fmod)
endif
Example
I used this in a project where I have a two main latex files, one for the main document and one for supplementary material. The project structure looks like this:
project/
main.tex
sup.tex
.local-vimrc
main-source/
input1.tex
input2.tex
sup-source/
input1.tex
input2.tex
I load a .local-vimrc file (using the plugin MarcWeber/vim-addon-local-vimrc), where I set g:Tex_MainFileExpression such that <leader>ll compiles main.tex if the file in the current buffer is located in the folder main-source and compiles sup.tex if it is in the folder sup-source. Below is my .local-vimrc file. I have very little experience with vimscript, so this is probably a littly hacky, but it might help to get an idea on how to use g:Tex_MainFileExpression. Also, I have modified it to be less messy and not tested the following code explicitly.
let g:Tex_MainFileExpression = 'g:My_MainTexFile(modifier)'
function! g:My_MainTexFile(fmod)
" Get absolute (link resolved) paths to this script and the open buffer
let l:path_to_script = fnamemodify(resolve(expand('<sfile>:p')), ':h')
let l:path_to_buffer = fnamemodify(resolve(expand('%:p')), ':h')
" Check if the buffer file is a subdirectory of `main-source` or `sup-source`
" stridx(a, b) returns -1 only if b is not substring of a
if stridx(l:path_to_buffer, 'main-source') != -1
let l:name = 'main.tex'
elseif stridx(l:path_to_buffer, 'sup-source') != -1
let l:name = 'sup.tex'
else
echom "Don't know what's the root tex file. '".#%."' is not in 'main-source/' or 'sup-source/' directory."
return ''
endif
" Concatenate this script path with main latex file name
" NOTE: this assumes that this script is located in the same folder as the
" main latex files 'main.tex' and 'sup.tex'
let l:path = l:path_to_script.'/'.l:name
return fnamemodify(l:abs_path_main, a:fmod)
endfunction
I'm working with AutoIt, and I was wondering in there is a method I can use to append a string of text to the end of a line inside a text file. I've been browsing all over autoit forums and there are lots of answers that are really close, but I have not found a solution that has actually worked for me.
The function:
FileWriteLine($LOG, "FText")
just adds a whole new line at the bottom, while the function:
_FileWriteToLine($LOG, 1, "FText", 0)
adds the letters "FText" to the beginning of the first line in the log file.
Is there any way I can add this text to the end of the first line, instead of the beginning?
I have never come up with this problem but just thinking of it, how about reading the whole line, storing it in a variable, add the extra test you want in the end of the line and then write the new line as it is modified replacing the old line???
You can use the FileWrite function: FileWrite documentation
You can create your own file writing function to include the opening, writing, and closing of the file like this:
Func WriteToLog($FileName, $Value)
$FileHandle = FileOpen($FileName, 1) ; 1 = append mode
If $FileHandle <> -1 Then
FileWrite($FileHandle, $Value)
EndIf
FileClose($FileHandle)
EndFunc
Then using your example and assuming $LOG is the file name for your log file, you can simply call your function whenever you need to log something:
WriteToLog($LOG, "FText")
I'm trying to build a very basic AutoLisp interface. I'm a total beginner at this, so after failing to code this from scratch, I turned to studying DCL properly. I followed this tutorial:
http://www.afralisp.net/dialog-control-language/tutorials/dialog-boxes-and-autolisp-part-1.php
And I got the same error. AutoCAD basically exits from executing the function, as if the dcl file wasn't even there.
I tried typing the address completely into it, but I think it should be able to work simply like linking HTML to images found in the same folder.
Below you have my code:
DCL:
samp1 : dialog {
label = "Structural Holes";
ok_cancel;
}
Lisp:
(defun C:samp1()
(setq dcl_id (load_dialog "samp1.dcl"))
(if (not (new_dialog "samp1" dcl_id))
(exit)
)
(action_tile
"cancel"
"(done_dialog)(setq userclick nil)"
)
(action_tile
"accept"
"(done_dialog)(setq userclick T))"
)
(start_dialog)
(unload_dialog dcl_id)
(princ)
)
(princ)
Thanks to anyone who will take the time to help me out with this. I'm starting to be quite desperate and it's my first and only autolisp project, so I have no experience whatsoever...
LE: Please note that the dcl file and the lisp file are both found in the same folder, no other subfolders or anything else.
Could not find **.DCL file
error: quit / exit abort
error: LOAD failed
This usually means the autolisp file or DCL file could not be found. To solve this problem, make sure you put your autolisp and DCL files inside the AutoCAD search path. To be more specific, put them in a directory that is part of your "Support File and Search Path". To find the AutoCAD support file and search path list, do the following:
In AutoCAD, click on the TOOLS drop down menu.
Go to the OPTIONS menu item.
Click on the FILES tab.
Click on the plus sign + in front of SUPPORT FILE AND SEARCH PATH.
This is your search path location. The directories listed there are searched in order, from top to bottom for any autolisp program you try to load. It is also used to find blocks and DCL files.
Either add the directory you store your autolisp and DCL files, or move your autolisp and DCL files into one of the directories listed here. This should end the errors listed above.
I came across this piece of information by accident here:
http://www.jefferypsanders.com/autolisp_nodcl.html
HUGE THANKS to JefferyPSanders for that......
For what its worth, you can also create a dialog on the fly in a "known directory" (like the directory AutoCAD resides in for example). The following will demonstrate that.
(defun _make-getstring-dialog-on-the-fly ( / fn f dcl dcl_id userclick str)
(setq fn (strcat
(vl-filename-directory
(findfile "acad.exe")) "\\$vld$.dcl")
f (open fn "w")
dcl
'(
"stringdlg : dialog {"
"label = \"Charater Array\";"
": edit_box {"
"label = \">>:\";"
"edit_width = 20;"
"key = \"stringdlg\";"
"is_default = true;"
"}"
": row {"
"alignment = centered;"
"fixed_width = true;"
" : button {"
" label = \"OK\";"
" key = \"dcl_accept\";"
" width = 10;"
" allow_accept = true;"
" }"
"}"
"}"
)
)
(mapcar
(function
(lambda ( x )
(write-line x f)
(write-line "\n" f)))
dcl)
(close f)
(setq dcl_id (load_dialog fn))
(new_dialog "stringdlg" dcl_id)
(action_tile "stringdlg" "(setq str $value)(done_dialog)")
(setq userclick (start_dialog))
(unload_dialog dcl_id)
str
)
I want to use vim to write a part of my file to another file. For example, I have the following file:
This is line 1
and this is the next line
I want my output file to read:
line 1
and this is
I know how to use vi to write a range of lines to a file:
:20,22 w partial.txt
An alternative is to visually select the desired text and then write:
:'<'> w partial.txt
However, when using this method, vim insists on writing the full line in the output, and I have found no way to write a partial line. Any thoughts?
I've got two (very similar) approaches to this. There's no way to do it with the built in write command, but it's fairly easy to generate your own function that should do what you want (and you can call it what you like - even W if you want).
A very simple approach that will only handle single-line ranges is to have a function like this:
command! -nargs=1 -complete=file -range WriteLinePart <line1>,<line2>call WriteLinePart(<f-args>)
function! WriteLinePart(filename) range
" Get the start and end of the ranges
let RangeStart = getpos("'<")
let RangeEnd = getpos("'>")
" Result is [bufnum, lnum, col, off]
" Check both the start and end are on the same line
if RangeStart[1] == RangeEnd[1]
" Get the whole line
let WholeLine = getline(RangeStart[1])
" Extract the relevant part and put it in a list
let PartLine = [WholeLine[RangeStart[2]-1:RangeEnd[2]-1]]
" Write to the requested file
call writefile(PartLine, a:filename)
endif
endfunction
This is called with :'<,'>WriteLinePart test.txt.
If you want to support multiple line ranges, you could either expand this to include varying conditions, or you could pinch the code from my answer to this question. Get rid of the bit about substituting backslashes and you could then have a very simple function that does something like (untested though...) this:
command! -nargs=1 -complete=file -range WriteLinePart <line1>,<line2>call writelines([GetVisualRange()], a:filename)